2009-08-07 18 views
6

NSOperation ve observer ile ilgili bir sorun yaşıyorum. Ben, bir tabbarcontroller ve bir splashController. Ben bir tabbarcontroller ve bir splashController var. Sıçrama ekranı yükünü indirmek ve dosyayı indirmek istiyorum ve dosya indirildiğinde ekrana tabbarcontroller görünmesini sağlayın.NSOperasyon, gözlemci ve iş parçacığı hatası

bool _WebTryThreadLock (bool), 0x3d2fa90: Web ana iş parçacığı veya web parçacığı dışında başka bir iş parçacığı gelen kilitlemek elde etmeye çalıştı

sorun

i 'bir hata ettik olmasıdır. Bu, , ikincil bir dişten UIKit çağrısının sonucu olabilir. ... Şimdi ezmeye

Bu benim kodudur:

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

    queue = [[NSOperationQueue alloc] init]; 


    NSString *path = [NSString stringWithFormat:@"%@flux.xml",DOCPATH]; 
    //Le fichier existe dans le repertoire des documents 
    if([[NSFileManager defaultManager] fileExistsAtPath:path]) 
     [window addSubview:tabBarController.view]; 
    else 
    { 
     splash = [[SplashController alloc] init]; 
     [window addSubview:splash.view]; 
    } 

    DataLoadOperation *operation = [[DataLoadOperation alloc] initWithURL:[NSURL URLWithString:@"http://sly.33.free.fr/flux.xml"]]; 
    [self.queue addOperation:operation]; 
    [operation addObserver:self forKeyPath:@"isFinished" options:NSKeyValueObservingOptionNew context:nil]; 


} 

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    [window addSubview:tabBarController.view]; 
    [window makeKeyAndVisible]; 
    NSLog(@"fini"); 

} 

kimse bana yardımcı olabilir mi? Gözlemlenen özelliğin değiştirildiği aynı iş parçacığı üzerinde anahtar-değer gözlemleme bildirimleri gerçekleşir.

cevap

20

Elma NSOperation sınıfı başvurusundaki aşağıdaki uyarıyı bahseder:

"Eğer bu özelliklerin gözlemci ekleyebilir rağmen, kullanıcı arayüzü ile ilişkili uygulamanın kullanıcı arabirimi Kanununun elemanlarına bunları bağlamak için Kakao bağlamaları kullanmamalısınız. Genellikle yalnızca uygulamanızın ana iş parçacığında çalıştırılmalıdır. Bir işlem herhangi bir iş parçacığında yürütülebileceği için, bu işlemle ilişkili herhangi bir KVO bildirimi herhangi bir iş parçacığında benzer şekilde ortaya çıkabilir. "

observeValueForKeyPath:ofObject:change:context: yönteminizde, ana iş parçacığı üzerinde herhangi bir UIKit işlemi gerçekleştirmelisiniz. Orada birden fazla adım gerçekleştirdiğinizden, aslında -dataLoadingFinished adlı gözlemleme sınıfınızda, ana iş parçacığı içinde observe:… içinden arayabileceğiniz başka bir yöntem oluşturmak isteyebilirsiniz. Daha sonra arayüzünün tüm ziyade her biri için performSelectorOnMainThread aramak zorunda kalmak yerine orada çağırır şunları içerebilir: parçacığı bir sorun oluşturmadığı durumlarda bile

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    [self performSelectorOnMainThread:@selector(dataLoadingFinished:) withObject:nil waitUntilDone:YES]; 
} 

, aslında her uygulamaya ayrı yöntemlerini tanımlamak için gelenektir Gözlemleme eylemi, observe:…'un büyümesini önlemek için çok büyük. Ayrıca, yalnızca bir özelliği gözlemlemiş olsanız bile, ilgilendiğiniz mülkün değişiklik bildirimini isteyen kişi olduğunu doğrulamak yine de daha iyi bir uygulama olduğunu unutmayın. Bunu yapmanın en iyi yolu için Dave Dribin'in makalesine bakın: Proper KVO Usage.

İlgili konular