Вопрос по nsoperation, ios, objective-c – Вернуть данные из NSOperation?

6

Я создаю многоNSOperations (подклассы), которые сортируют кучу данных. Когда они'готово, яони мне нравятсявернуть" эти данные и положить его в изменяемый массив или что-то. Заказ не делаетне имеет значения.

Возможно ли что-то подобное?

Ваш Ответ

2   ответа
14

ример, в некоторых случайныхNSURLConnection на основе операции, я определяю блок завершенияtypedef (просто для упрощения синтаксиса блока позже), который возвращаетNSData в случае успеха илиNSError если не:

typedef void(^CustomOperationCompletionBlock)(NSData *data, NSError *error);

Затем я могу определить свойство блока для моегоNSOperation подкласс, например: я

@property (nonatomic, copy) CustomOperationCompletionBlock successFailureBlock;

Я буду часто исполнять моюinit метод моей работы, который позволит мне установить этот блок завершения во времяinit процесс (в дополнение ко всему, что я хочу инициализировать):

- (instancetype)initWithURL:(NSURL *)url successFailureBlock:(CustomOperationCompletionBlock)successFailureBlock;

Мои различные методы, которые обрабатывают ошибки и / или успех внутри моей операции, будут вызывать этот блок завершения для передачи данных обратно:

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    if (self.successFailureBlock) {
        // whether you call the completion block on the main queue, or use whatever queue the operation is using, is up to you. Here I'll call the completion block on the main queue:

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.successFailureBlock(nil, error);
        }];
    }

    [self completeOperation];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    if (self.successFailureBlock) {
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.successFailureBlock(self.data, nil);
        }];
    }

    [self completeOperation];
}

И чтобы использовать эту операцию с пользовательским обработчиком блока завершения, когда я начинаю свою операцию, я могу просто передать ей специальный блок завершения. Например, это сохраняет данные в случае успеха или регистрирует ошибку, если нет:

CustomOperation *operation = [[CustomOperation alloc] initWithURL:url successFailureBlock:^(NSData *data, NSError *error) {
    if (error)
        NSLog(@"CustomOperation error: %@", error);
    else         
        [data writeToFile:path atomically:YES];
}];

[queue addOperation:operation];

Очевидно, вы бы поменяли блокtypedef передать обратно любые объекты, которые имеют смысл для вашей работы. Но это иллюстрирует базовую схему блочного механизма дляNSOperation подкласс для возврата данных.

Хороший ответ, Роб. Lorenzo B
4

ния операции

if([self.delegate respondsToSelector:@selector(YourDelegate:)]) {
    [(NSObject *)self.delegate performSelectorOnMainThread:@selector(YourDelegate:) withObject:self waitUntilDone:NO];
}

В интерфейсе

-(void)YourOperationDidFinish:(YourOperation *)downloader {
    if(downloader.downloadItem) {
        // processing with your object       
    }
}
+1 Очевидно, вы должны ссылаться на то же имя метода в@selector и метод в делегате. Например, если метод в делегатеyourOperationDidFinish:, затем вы'д ссылка@selector(yourOperationDidFinish:), Лучше, вы, вероятно, должны определитьпротокол для делегата, чтобы устранить любую двусмысленность здесь. Кроме того, подразумевается в этом ответе, было бы разумно объявитьdelegate имущество .weak Rob

Похожие вопросы