我NSOperation和观察者有问题.
我有一个tabbarcontroller和一个splashController.我想加载启动画面并下载文件,下载文件后tabbarcontroller会显示在屏幕上.
问题是我有一个错误:
bool _WebTryThreadLock(bool),0x3d2fa90:试图从主线程或Web线程以外的线程获取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");
}
谁能帮助我?
Sea*_*phy 20
键值观察通知发生在更改被观察属性的同一线程上.Apple在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的文章" 正确的KVO使用情况 ",了解执行此操作的最佳方法.
| 归档时间: | 
 | 
| 查看次数: | 6651 次 | 
| 最近记录: |