Реализация AsyncTask с использованием NSOperation в iOS

Я реализовал AsyncTask (Android) в iOS, используя подкласс NSOperation.

-(id)initWithParam:(NSArray *)params{

if (self = [super init]) {

paramsArray = params;
}
return self;

}

- (void)start {

         @autoreleasepool {

   if (self.isCancelled)
      return;
   NSInteger result;

   result = [self doInBackground:paramsArray];

dispatch_async(dispatch_get_main_queue(), ^{

    [self postExecute:result];
});
}
}


 - (BOOL) doInBackground: (NSArray *) parameters{

   BOOL status = false;
   int i;
 for (i=0; i<100000; i++) {
     NSLog(@"printing i::%d",i);
 }
 if (i == 100000) {
    status = YES;
 }

return status;
}
- (void) postExecute: (BOOL) deviceState{

   if (deviceState) {
      NSLog(@"Finished");
  }

}

-(BOOL)isConcurrent{

   return YES;
}

Это то, как я реализовал в iOS. Пожалуйста, предложите и все, что я хочу добавить для этой функциональности.

А также, когда я могу вызвать isExecuting и isFinished в подклассе NSOperation


person iOS    schedule 26.12.2014    source источник


Ответы (1)


Отвечая на ваш вопрос, к сожалению, нет, эта реализация неверна. Близко, но не совсем там.

Несколько вещей:

  1. Ваш пример не является параллельной операцией. В случае NSOperation термин параллельная операция (теперь называемая асинхронной операцией) имеет особое значение. Асинхронная операция — это операция, которая продолжает выполняться асинхронно даже после завершения метода start. И вы указываете это, возвращая YES из isConcurrent (в старых версиях iOS) и isAsynchronous (в современных версиях iOS). Но примерная операция в вопросе полностью выполняется, когда start заканчивается, поэтому это не асинхронная операция, и поэтому isConcurrent и isAsynchronous должны возвращать NO.

    Предположим в этом примере, что вы изменили isConcurrent, чтобы вернуть NO, что соответствует тому, что вы делаете в start. Это исправит эту операцию. Но не позволяйте этому сбить вас с толку. Если вы добавите эту операцию в свою собственную очередь операций, она все равно будет выполняться асинхронно/одновременно по отношению к основной очереди, просто это операция, которая автоматически завершается, когда завершается start, и поэтому isAsynchronous/isConcurrent должно возвращать NO.

  2. Вы спрашиваете, когда я могу позвонить isExecuting и isFinished? Как правило, вы не вызываете эти методы. Обычно вы реализуете эти методы. В частности, когда асинхронная операция в конечном итоге завершается, вы должны убедиться, что приложение (а) публикует KVN для ключей isExecuting и isFinished; и (б) вы переопределяете isExecuting и isFinished, чтобы гарантировать, что они соответственно возвращают соответствующие значения.

    Вам нужно реализовать этот код isExecuting и isFinished только тогда, когда операция действительно является асинхронной/параллельной операцией. См. раздел Настройка операций для параллельного выполнения документа Руководство по параллельному программированию: Очереди операций. Также см. вводный раздел NSOperation определение класса.

Неясно, должна ли ваша операция быть асинхронной или нет (и даже нужно ли вам вообще создавать подкласс NSOperation). Это полностью зависит от того, какую задачу вы хотите выполнить, и от того, выполняется ли сама задача асинхронно или нет.

person Rob    schedule 26.12.2014
comment
Большое спасибо @Rob. На самом деле я положил образец там. На самом деле моя задача - подключиться к пользовательскому устройству Wi-Fi и прочитать данные с устройства. Вот почему я выбираю подкласс NSOperation - person iOS; 26.12.2014
comment
Да, это может быть хорошим примером того, что вы бы обернули подклассом NSOperation. Вопрос просто в том, является ли операция действительно параллельной (т. е. start просто инициирует соединение, и есть некоторый шаблон делегата или блока завершения, который будет вызван позже) или нет (т. е. start откроет соединение с устройством Wi-Fi и не вернется, пока соединение не будет установлено). с устройством было покончено). Я предполагаю, что это первое, но ваш пример в вашем вопросе больше похож на последний. - person Rob; 26.12.2014