6

Bazı kodlarla çalışıyorum, NSOperation s içinde yeni olduğum çalışma döngülerine rastlıyorum.NSOperasyonda NSThread uyku kullanma

NSOperation s veri yüklenirken meşgul - ve meşgul olduklarında, indirme işlemlerinin tamamlanmasını beklemek için NSRunLoop s ve iş parçacığı uyku biçiminde bir kod var. Ben koşmak döngüler hakkında okudum

while (aCertainConditionIsTrue && [self isCancelled]==NO) { 
    if(![[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]){ 
     [NSThread sleepForTimeInterval:1.0]; 
    } 
} 

ve runMode:beforeDate: bir giriş kaynağı veya zaman aşımını bekler:

özellikle bu kod bana ilgi olduğunu. Her ne kadar% 100'lük olmasa da, bir girdi sosu olarak sayılır.

Bunun ilk çalıştırmasında, her zaman NO değerini döndürür ve sleepForTimeInterval: değerini gösterir. Bu kötü mü?

Belirli bir yardımcı program sınıfında, her bir iş parçacığı için sleepForTimeInterval: numarasına çok fazla isabet ediyor; bu da performansı önemli ölçüde azaltıyor.

Bunun için daha iyi çözümler veya tavsiye?

cevap

2

Uyku, parçayı kilitler. Belki de performSelector: withObject: afterDelay kullanmak için kodunuzu değiştirirsiniz. Bu şekilde iş parçanız çalışmaya devam edebilir. Bir eşzamanlı NSOperation kullanmak gerekir gibi

... 
    done = NO; 
    [self checkDoneCondition:nil]; 
    ... 

- (void)checkDoneCondition:(id)object { 
    if (aCertainConditionIsTrue && [self isCancelled]==NO) { 
     if(...) { 
      [self performSelector:@selector(checkDoneCondition:) withObject:[con error] afterDelay:1.0]; 
     } else { 
      done = YES; 
     } 
    } 
} 
1

görünüyor. Eşzamanlı çalışır olmayan bir eşzamanlı operasyon, aksine

bir eşzamanlı operasyon uyumsuz olarak çalışır: Burada Elma docs ilgili bir parçasıdır. Diğer bir deyişle, eşzamanlı bir işlemin başlatma yöntemini çağırdığınızda, ilgili yöntem tamamlanmadan önce bu yöntem geri dönebilir. Bu işlem, olabilir çünkü işlem nesnesi, görevi yürütmek için yeni bir iş parçacığı oluşturdu veya işlem eşzamansız işlev olarak adlandırıldı. Denetimin arayana geri döndüğünde yalnızca devam ederse, işlem devam ediyorsa, aslında önemli değildir. (...) Eşzamanlı bir işlemde, başlangıç ​​yönteminiz, işleminin başlatılmasını eşzamansız bir şekilde başlatır. Bir iş parçacığı oluşturduğunuzda veya eşzamansız bir işlev çağırdığınızda, bunu bu yöntemden yaparsınız. İşlemi başlattığınızda, başlangıç ​​yönteminiz, isExecuting yöntemi tarafından bildirilen işlemin yürütme durumunu da güncelleştirmelidir. Bunu, ilgili istemcilere işleminin çalışmakta olduğunu bilmelerini sağlayan isExecuting anahtar yolu için KVO bildirimleri göndererek yaparsınız. IsExecuting yönteminiz de durumunu iş parçacığı güvenli bir şekilde döndürmelidir.

(https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html itibaren) Diğer bir deyişle, size NSOperation alt sınıfta -start yöntemini geçersiz ve executing ve finished özelliği için ivar sahip olabilir. Bu yöntem, indirmeyi ayrı bir iş parçacığında başlatır. İndirme başladığında, executing bayrağını ve KVO'yu tetiklersiniz.Bu iş parçacığı bittiğinde, aynı şeyi finished ve executing ile yapın. Karmaşık görünüyor ama aslında oldukça basit.

Ayrıca büyük bir açıklama ile Stack Overflow bu soruyu bakın: Subclassing NSOperation to be concurrent and cancellable