ios停止2个线程同时使用方法

时间:2012-07-05 06:45:36

标签: objective-c ios multithreading

我们遇到了一个错误,它破坏了我们UI的外观,一些UI元素重叠,或者已经被添加到子视图两次。这个bug几乎没有复制,所以很难修复它。现在我想到了原因,可能改变UI的方法同时被调用了两次。我是对的,我试图以编程方式创建错误。

我们有一个错误,它是由不同线程同时访问的方法引起的。要模仿这个问题,并更好地理解它。见下面张贴的代码。

当我执行此操作时,updatePresence方法调用,我的程序完美运行

ViewController.m

-(void)loadConversationScreen{
    [conversationController updatePresence];
}

但是当我这样做时,我的程序出了问题

ViewController.m

-(void)loadConversationScreen{
    [conversationController performSelectorInBackground:@selector(updatePresence) withObject:nil];
    [conversationController updatePresence];

}

这是因为正在同时访问该方法,并且同时也正在访问/更改我的UIView实例。

如何 正确 阻止两个线程同时使用某个方法?

如何在IOS中正确处理它(如果没有正确的方法,有什么工作),是否有内置锁或某些内容?

我的应用应该支持ios 4.0及更高版本

感谢所有人的帮助。

2 个答案:

答案 0 :(得分:5)

最好的线程锁定是@sycnhronized(object) {}。这意味着一次只能有一个线程输入代码。传入的对象用于执行锁定;只有一个线程可以进入受特定对象保护的块,一次同步。其他人会等。这可以是任何Objective-C对象,甚至是NSString

通常,您将使用您尝试保护的任何对象来保护多个线程。您可能需要@synchronized(self) {}

-(void)updateVariables {
    @synchronized(self) {
        _foo = 1;
        _bar = 2;
    }
}

@sycnhronized是可重入的,因为同一个线程可以根据需要深入调用@sycnhronized,例如:

- (void)a {
    @synchronized(self) {
        // entered "immediately" if called from b, where the @synchronized has
        // already been called
        _foo = _foo + 1;
    }
}

- (void)b {
    @synchronized(self) {
        [self a];
    }
}

对于后代而且因为我在阅读你的澄清之前已经输入了它,如果你真的只关心更新用户界面,你会想要强制你的主叫线程,而不是像这样:

- (void)someTask {
    dispatch_async( dispatch_get_main_queue(), ^{
        [self updateUI];
    });
}

- (void)updateUI {
    NSAssert( [NSThread isMainThread], @"called from non-main thread" );
    // do UI updates here
}

答案 1 :(得分:2)

正如warrenm所说,你不应该从主线程(UI线程)以外的其他线程更新你的UIView。不过,你问是否有任何解决方法可以解决的问题。说实话,你应该尝试,而不是阻止第二个线程访问你的方法,理解为什么方法被调用两次。这是一个比其他任何事情更合乎逻辑的问题,你应该尝试解决这个问题,而不是尝试快捷方式。