Наследование, AFNetworking, хорошие практики?

#ios #inheritance #nsurl #afnetworking-2 #nsurlsession

#iOS #Наследование #nsurl #afnetworking-2 #nsurlsession

Вопрос:

Я работаю над приложением, которое будет подключаться к разным поставщикам данных, поскольку я начал разрабатывать разные классы для работы с этими поставщиками, я начал видеть сходство между нужными мне функциями. итак, я решил создать базовый classs, который наследуется от NSObject , и предоставить некоторые свойства и методы для этого класса, которые определенно появляются во всех клиентах.

Это базовый класс

 @interface AhmBaseDataLoader : NSObject {
    NSMutableArray *elementsArray;
}

- (void)loadElements:(NSString *)searchValue;
@property (nonatomic, strong) NSArray *Elements;
 

И у меня есть около четырех классов, наследующих этот класс, все они должны

 loadElements:(NSString *)searchValue {
   //I dO some data work here using NSURL and basic classes
    NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
}
 

До сих пор я использовал basic NSURLSession work в подклассах для загрузки данных. До сих пор все работало нормально. Все это происходит в фоновых потоках. процесс загрузки http иногда может быть длительным, и мне нужно иногда иметь возможность отменить этот процесс.

Итак, мой вопрос в том, что при такой настройке полезно ли включать afnetworking? Я знаю, что он очень популярен и очень быстр, но я в замешательстве, если бы я его использовал, я бы наследовал от AFHTTPSessionManager своего базового загрузчика или создал его как свойство? Что было бы рекомендовано для моего сценария?

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

1. да, наследование собственного класса от AFHTTPSessionManager является очень распространенной практикой. вы можете настроить requestSerializer и responseSerializer в унаследованном классе, или даже вы можете определить все свои собственные запросы с помощью собственных обработчиков завершения.

Ответ №1:

AFNetworking — очень хорошая библиотека для работы в сети. Если вам нужно что-то более продвинутое, чем базовые вещи, и вы не хотите переопределять их самостоятельно, это хороший (лучший?) выбор. Обратите внимание, что AF 2.0 несовместим со старыми версиями OSX и iOS, поэтому обратите внимание на то, какую версию AF вы используете.

О вашей проблеме. Я не поклонник подклассов. Иногда есть классы, которые вы хотите подклассировать (например UIView , UIViewController , …), потому что они предназначены для этого. Но для более «полных» классов их чаще используют. И если вам нужно настроить поведение, обычно они предоставляют методы делегирования. На вашем месте я бы добавил свойство типа AFHTTPSessionManager (если вы используете AF 2.0) во все ваши объекты

 @property (nonatomic, strong) AFHTTPSessionManager *httpSessionManager;
 

и loadElementes: просто используйте это.
В вашем AppDelegate или там, где вы создаете свои объекты, я бы создал менеджер и установил его для каждого объекта. Итак, что-то вроде

 AFHTTPSessionManager *httpSessionManager = ... //;
AhmBaseDataLoader *myFirstLoader = [[AhmBaseDataLoader alloc] init];
myFirstLoader. httpSessionManager = httpSessionManager;
 

РЕДАКТИРОВАТЬ: если вы используете AF 1.X по соображениям совместимости (как и я), вы должны использовать AFHTTPClient вместо AFHTTPSessionManager

РЕДАКТИРОВАНИЕ 2: относительно вашего первого комментария. Ваш суперкласс будет иметь AFHTTPSessionManager , и все ваши подклассы будут иметь к нему доступ, это правда. И я предполагаю, что они используют его во время loadElements: метода (или любого другого метода на самом деле). Конечно, у вашего суперкласса может быть метод инициализации. Я думаю, что для всех подклассов может быть только один диспетчер сеансов (поправьте меня, если я ошибаюсь. Он использует очередь для загрузки данных, поэтому вам не нужно беспокоиться о сериализации запросов). Итак, я предполагал, что в классе, в котором вы создаете свои подклассы (например, ваш AppDelegate), вы сначала создаете диспетчер сеансов, а после устанавливаете его для всех своих объектов. Например:

 //AppDelegate.m
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    ...
    AFHTTPSessionManager *httpSessionManager = ... //; create the session and configure it

    AhmBaseDataLoader *myFirstLoader = [[AhmDerived1DataLoader alloc] init];
    myFirstLoader. httpSessionManager = httpSessionManager;
    AhmBaseDataLoader *mySecondLoader = [[AhmDerived2DataLoader alloc] init];
    mySecondLoader. httpSessionManager = httpSessionManager;
    AhmBaseDataLoader *myThirdLoader = [[AhmDerived3DataLoader alloc] init];
    myThirdLoader. httpSessionManager = httpSessionManager;
    AhmBaseDataLoader *myFourthLoader = [[AhmDerived4DataLoader alloc] init];
    myFourthLoader. httpSessionManager = httpSessionManager;


}
 

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

1. Я использую AF 2.0 и iOS 7.1, что касается вашего ответа, так что теперь я могу добавить AFHTTPSessionManager в суперкласс, и все наследующие классы будут иметь к нему доступ. Но инициализация произойдет в подклассе, а не в суперклассе. Это звучит правильно?

2. Просто уточняющее замечание: AFNetworking 2 поддерживает iOS 6 и OS X 10.8, поэтому вам нужно использовать AFNetworking 1 только в том случае, если вы поддерживаете iOS 5 / OS X 10.7.

3. @AaronBrager Так сказано на домашней странице проекта. Но также говорится, что если вы используете AFHTTPSessionManager (это то, что хочет использовать Эдди), то требования — iOS 7 или OS X 10.9.