NSOperation,观察者和线程错误 [英] NSOperation, observer and thread error

查看:104
本文介绍了NSOperation,观察者和线程错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've got a problem with NSOperation and observer.

我有 tabbarcontroller 和一个 splashController 。我想加载启动画面并下载文件,当文件下载时,屏幕上会显示 tabbarcontroller

I've a tabbarcontroller and a splashController. I want the splashscreen load and download the file and when the file is downloaded make the tabbarcontroller appear to the screen.

问题是我有一个错误:


bool _WebTryThreadLock(bool),0x3d2fa90:试图获取网络锁
来自主线程或Web线程以外的线程。这可能是
是从辅助线程调用UIKit的结果。现在崩溃
...

bool _WebTryThreadLock(bool), 0x3d2fa90: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...

这是我的代码:

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

}

有人可以帮助我吗?

推荐答案

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

Key-value observing notifications occur on the same thread in which the observed property was changed on. Apple mentions the following warning in the NSOperation class reference:


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

"Although you can attach observers to these properties, you should not use Cocoa bindings to bind them to elements of your application’s user interface. Code associated with your user interface typically must execute only in your application’s main thread. Because an operation may execute in any thread, any KVO notifications associated with that operation may similarly occur in any thread."

在你的 observeValueForKeyPath:ofObject:change:context:方法中,你应该在主线程上执行任何UIKit操作。由于你在那里执行了多个步骤,你可能真的想在你的观察类中创建一个名为 -dataLoadingFinished 的另一个方法,你可以从观察:... 。然后,您可以在其中包含所有UI调用,而不必为每个调用 performSelectorOnMainThread

In your observeValueForKeyPath:ofObject:change:context: method, you should perform any UIKit operations on the main thread. Since you're performing multiple steps in there, you might actually want to create another method in your observing class called -dataLoadingFinished which you can call on the main thread from inside observe:…. You can then include all of your UI calls in there, rather than having to call performSelectorOnMainThread for each one:

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

即使在线程不是问题的情况下,习惯上也要单独定义实际实现每个观察动作的方法,以防止观察:... 增长过大。

Even in cases where threading is not an issue, it is customary to define separate methods to actually implement each observation action, to prevent the observe:… from growing too large.

另请注意即使您只观察一个属性,仍然更好的做法是验证您感兴趣的属性是提示更改通知的属性。请参阅Dave Dribin的文章正确的KVO用法最佳方式。

Also note that even though you are only observing one property, it is still better practice to validate that the property you are interested in is the one prompting the change notification. See Dave Dribin's article Proper KVO Usage for the best way in which to do this.

这篇关于NSOperation,观察者和线程错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆