2013-10-15 30 views
6

Bir sürü veriyi sıralayan çok sayıda NSOperation s (alt sınıf) oluşturuyorum. İşin bittiğinde, bu verileri "geri döndürmelerini" ve bunu değiştirilebilen bir diziye ya da başka bir şeye yerleştirmelerini isterim. Sipariş önemli değil.NSOperation'dan veri dönüşü mü?

Böyle bir şey mümkün mü?

cevap

4

Elbette. NSOperation alt sınıfında bir temsilci ilan edin. Daha sonra kullanıcı arayüzünde

-(void)YourOperationDidFinish:(YourOperation *)downloader { 
    if(downloader.downloadItem) { 
     // processing with your object  
    } 
} 
+1

+1 Açıktır ki, '@ selector'da aynı yöntem adına ve temsilci yöntemine başvurmalısınız. Örneğin, temsilci içindeki yöntem 'yourOperationDidFinish:' ise, o zaman '@selector (yourOperationDidFinish:)' ifadesini kullanırsınız. Daha iyi, muhtemelen bir [protokol] tanımlamanız gerekir (https://developer.apple.com/library/ios/documentation/general/conceptual/DevPedia-CocoaCore/Protocol.html#//apple_ref/doc/uid/TP40008195-CH45 -SW1) delege için, burada herhangi bir belirsizliği ortadan kaldırmak için. Ayrıca, bu cevapta örtük, 'delegate' özelliğini 'zayıf' ilan etmek ihtiyatlı olacaktır. – Rob

14

olarak işlem

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

sonra bitiş protokol temsilci desene alternatif bir tamamlama bloktur.

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

sonra bir tanımlayabiliriz: Örneğin, rastgele NSURLConnection göre işlemde, bir typedef (sadece daha sonra blok sözdizimi kolaylaştırmak için) bir NSData başarılı ise, ya da bir NSError değilse döndüren bir tamamlama bloğu tanımlayan benim NSOperation alt sınıf, eg özelliğini engellemek:

@property (nonatomic, copy) CustomOperationCompletionBlock successFailureBlock; 

sık sık benim operasyonun benim init yönteminin bir yorumu gerekecek anythin ek olarak (bana init işlemi sırasında tamamlama bloğu ayarlamak izin verir g Başka I) başlatmak istiyorum: sonra tekrar veri aktarmak için tamamlanmasının bloğunu çağırır ameliyatım içindeki hataları ve/veya başarıyı işlemek

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

Benim çeşitli yöntemler:

- (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]; 
} 

Ve etmek İşlemi başlattığımda özel tamamlama blok işleyicisi ile bu işlemi kullanıyorum, özel bir tamamlama bloğunu geçebilirim. Örneğin, bu başarılı olursa verileri kaydeder, ya değilse hatayı kaydeder: Açıkça

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]; 

, geri operasyon için anlamlı olabilecek her nesneleri geçmek bloğu typedef değişirdi. Ancak bu, verileri döndürmek için NSOperation alt sınıfı için blok tabanlı bir mekanizmanın temel modelini gösterir.

+1

İyi cevap Rob. –