2009-08-07 77 views
6

我遇到了問題NSOperation和觀察者。NSOperation,觀察者和線程錯誤

我有一個tabbarcontrollersplashController。我想要加載splashscreen並下載文件,並且下載文件時,屏幕上會顯示tabbarcontroller

的問題是,我已經錯誤:

布爾_WebTryThreadLock(布爾),0x3d2fa90:嘗試以獲得將紙幅從比主線程或web線程以外的線程鎖定 。這可能是 是從輔助線程調用UIKit的結果。轟然 現在......

這是我的代碼:

- (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"); 

} 

誰能幫助我?

回答

20

鍵值觀察通知發生在觀察屬性被更改的相同線程上。蘋果提到的的NSOperation類引用以下警告:

「雖然可以將觀察這些特性,你不應該使用Cocoa綁定將其綁定與用戶界面相關的應用程序的用戶界面代碼的元素。通常必須僅在您的應用程序的主線程中執行,因爲某個操作可能在任何線程中執行,所以與該操作相關的任何KVO通知都可能類似地發生在任何線程中。

在您的observeValueForKeyPath:ofObject:change:context:方法中,您應該在主線程上執行任何UIKit操作。由於您在此處執行多個步驟,因此您可能實際上想要在您的觀測類中創建另一個名爲-dataLoadingFinished的方法,您可以從observe:…內部調用主線程。然後,您可以包括所有UI的調用在那裏,而不必調用performSelectorOnMainThread爲每一位:

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

其中線程是不是一個問題,它通常定義單獨的方法實際上實現每個觀察行動,防止observe:…增長過大。

另請注意,即使您只觀察一個屬性,驗證您感興趣的屬性是提示更改通知的屬性仍然更好。請參閱Dave Dribin的文章Proper KVO Usage,瞭解執行此操作的最佳方法。