NSOperation,观察者和线程错误

时间:2009-08-07 11:23:10

标签: iphone sdk

我遇到了NSOperation和观察者的问题。

我有tabbarcontrollersplashController。我希望启动启动画面并下载文件,下载文件后,屏幕上会显示tabbarcontroller

问题在于我发生错误:

  

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

}

有人可以帮助我吗?

1 个答案:

答案 0 :(得分:20)

键值观察通知发生在更改被观察属性的同一线程上。 Apple在NSOperation类引用中提到了以下警告:

  

“虽然您可以将观察者附加到这些属性,但您不应该使用Cocoa绑定将它们绑定到应用程序用户界面的元素。与用户界面关联的代码通常只能在应用程序的主线程中执行。因为操作可能在任何线程中执行,与该操作相关的任何KVO通知都可以类似地在任何线程中发生。“

observeValueForKeyPath:ofObject:change:context:方法中,您应该在主线程上执行任何UIKit操作。由于您在那里执行了多个步骤,您实际上可能希望在名为-dataLoadingFinished的观察类中创建另一个方法,您可以在observe:…内的主线程上调用该方法。然后,您可以在其中包含所有用户界面调用,而不必为每个调用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,了解实现此目的的最佳方式。