Могу ли я использовать блоки в асинхронных результатах с restkit?

#objective-c #asynchronous #objective-c-blocks #restkit

#objective-c #асинхронный #objective-c-блоки #restkit

Вопрос:

—ОБНОВЛЕНИЕ: я решил попробовать AFNetworking. Несмотря на то, что RestKit обладает действительно хорошей функциональностью отображения объектов, то, как были разработаны сетевые вызовы, усложнило для нас некоторые вещи.

Я надеюсь на несколько советов о том, как организовать мой проект, использующий RestKit.

У меня есть несколько вызовов REST из класса репозитория, и его результаты передаются контроллерам. Например, у меня есть метод getProfile в классе репозитория, который вызывается из нашего контроллера просмотра просмотра. Контроллер представления устанавливается в качестве делегата для вызовов get profile, в то время как класс репозитория устанавливается в качестве делегата для вызовов restkit.

Проблема в том, что если контроллер просмотра выполняет несколько запросов get profile, трудно определить, какой результат должен перейти к какой функции делегирования, поскольку все вызовы restkit используют один и тот же метод делегирования objectLoaderDidFinishLoading . Затем у меня есть 4 делегата, которым я должен сопоставить результаты 4 асинхронных запросов restkit.

Есть ли какой-либо способ, которым я могу использовать блоки, чтобы я мог передать функцию для выполнения, когда возвращается конечный результат, чтобы я мог назначить надлежащего делегата? Поддержка блоков, которую я видел, позволяла использовать блок до отправки запроса в rest kit, но я заинтересован в его использовании, когда возвращается асинхронный результат.

Альтернатива проверке результатов или настройке пользовательских данных и отслеживанию того, какой делегат идет с какими асинхронными результатами, кажется ненадежной и громоздкой.

Комментарии:

1. Вы видели это? github.com/gowalla/AFNetworking

2. Привет, Колин, это выглядит интересно, но мы уже вложили немало усилий в RestKit и также используем его отображение объектов..

3. Привет, Колин, мне любопытно, поддерживает ли AFNetworking сопоставление json с объектом?

4. Я считаю, что это так, поскольку он зависит от RestKit. Если нет, то это будет нетрудно выполнить самостоятельно; для этого существует множество библиотек.

Ответ №1:

Вы можете решить свои проблемы с устранением неоднозначности между запросами вашего профиля, используя непрозрачный указатель userData на RKObjectLoader. Это позволит вам привязать к запросу любой объект, который вы хотите, который затем можно использовать, чтобы помочь различать запросы нескольких профилей. Кроме того, если эти запросы профиля отправляются на разные пути к ресурсам, вы можете просто использовать метод wasSentToResourcePath: в RKObjectLoader, чтобы различать их.

Комментарии:

1. Я не хотел использовать userData, потому что они, по сути, содержали бы одну и ту же идентичную информацию, например, если бы я вызвал getProfile для одного и того же профиля из 4 разных источников, все они имели бы одинаковые пользовательские данные. Существуют работоспособные обходные пути, позволяющие отслеживать, какие пользовательские данные куда отправляются, но это кажется громоздким.. много операторов switch и if else для аналогичных запросов rest kit.

2. Хммм, пользовательские данные не будут содержать те же данные, если вы свяжете их с источниками, к чему и клонил @jeffarena. Сохраните UUID как userData в RKObjectLoader, а также используйте тот же UUID в качестве ключа словаря, значение которого является исходным. Это упрощает устранение неоднозначности ответов.

Ответ №2:

Я просто наткнулся на этот вопрос, пытаясь решить эту проблему для моего собственного интерфейса REST. Я рад, что сделал, я, вероятно, буду использовать RestKit сейчас.

Я отвлекся, возвращаясь к вашему вопросу. Как вы заметили, не похоже, что аргумент block в RKObjectManager предназначен для использования таким образом. Вместо этого, как насчет написания класса, который реализует RKObjectLoaderDelegate , принимает блок и вызывает этот блок при любом из вызовов делегата.

Может быть, что-то вроде этого?

 @interface MyObjectLoaderDelegate : NSObject <RKObjectLoaderDelegate>

@property (nonatomic, copy) void (^callback)(RKObjectLoader *loader, NSDictionary *objectDictionary, NSError *error)

- (id)initWithCallback:(void (^)(RKObjectLoader*, NSDictionary*, NSError*)aCallaback;

@end
 

И в любом реализованном методе делегирования вы можете выполнить блок. Поскольку блоки сохраняют переменные области видимости, вы можете запускать код против вызывающего делегата.

Что думаешь?

Комментарии:

1. Интересный подход, и я попробовал его версию, но столкнулся с ошибкой, поскольку у меня нет строгой ссылки на MyObjectLoaderDelegate. В моем классе repo в основном была фабрика objectloaderdelegate, которую я использую для установки в качестве делегата для вызова набора rest. К сожалению, restkit не сохраняет ссылку на делегат, и пользовательский делегат загрузчика больше не ссылается на загрузку объекта. Я все равно работал над сохранением массива блоков в репозитории, так что, возможно, я пойду по этому пути.

Ответ №3:

Я не уверен, что использование блоков — правильный способ решить вашу проблему.

Как насчет наличия класса getProfile, который реализует RKObjectLoaderDelegate. Итак, вы вызываете запрос изнутри здесь и устанавливаете себя в качестве делегата. Тогда у вас есть ObjectLoader для каждого запроса.

Итак, в вашем контроллере представления каждый раз, когда вы задаете getProfile, вы создаете экземпляр. И затем, когда этот экземпляр отправляет ваш контроллер обратно (через делегатов?) вы знаете, что это такое.

Я тоже только что столкнулся с этой проблемой, поэтому очень хочу услышать отзывы.

Комментарии:

1. Я сделал аналогичный комментарий к более раннему предложению, но похоже, что слабая ссылка на этот класс objectlaoderdelegate означает, что к тому времени, когда вызов restkit возвращается и вызывает делегата, ссылка на делегата исчезает. RestKit не сохраняет ссылки на делегатов, что означает, что мне придется сохранять ссылки на пользовательских делегатов в моем репозитории или в каком-либо другом классе … выполнимо, но, я думаю, очень громоздко

Ответ №4:

Кажется, что переход на AFNetworking — это правильный путь … это была гораздо более простая реализация того, что мне было нужно.

Комментарии:

1. Лично я не думаю, что добросовестно, что был задан вопрос о RestKit, люди изо всех сил старались ответить, и в итоге правильный ответ был отмечен как «Переключенный на сеть AF». Весь смысл задавать вопрос SO заключается в том, чтобы сообщество помогло в техническом вопросе?

2. Но вопрос заключался в том, можно ли использовать блоки, и ответ был отрицательным. Использование userdata для удаления не поддерживается ни в одном крупном проекте, поэтому AFNetworking кажется единственной альтернативой.