2012-07-05 29 views
3

我们有一个bug,它破坏了我们的UI的外观,一些UI元素重叠,或者已经被添加到子视图两次。该错误很难复制,因此很难修复它。现在我想到了原因,并且可能更改UI的方法被同时调用两次。我是正确的,我试图编程创建bug。 ios stop 2线程同时使用方法

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

当我这样做,updatePresence方法调用,我的程序完美的作品

ViewController.m

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

但是当我这样做,不顺心的事与我的计划

ViewController.m

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

} 

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

我如何PROPERLY站2条使用的方法在同一时间线?

我该如何正确处理它在IOS(如果没有正确的方法,有什么工作),有没有建立在锁或某种?

我的应用应该支持IOS 4.0及以上

提前感谢所有您的帮助。

+6

永远不要在后台线程上更新您的用户界面。 UIKit严格禁止它。 – warrenm

+0

嗯,谢谢,我不知道,但这只是一个尝试使用两个不同的线程同时更新它。该错误很难重现,但是当两个线程同时访问方法时发生错误 –

+0

performSelectorInBackground仅用于模拟不同线程上的方法访问,但实际上我并没有在我们的代码中执行此操作。谢谢你通知我这是非法的。我学到了一些新东西。那么有人能帮我解决我的问题吗? –

回答

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]; 
    } 
} 

为后人因为我已经输入它在阅读你的说明之前,如果你真的只关心更新UI,你想强制你的呼叫转到主线程,而不是像这样:

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

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

我试图研究@synchronized的事情,这是我第一次使用它,你能给我一个关于如何同步可以应用在我的代码的简短例子吗? –

+0

无论如何,感谢这个答案,我只会做更多关于这个和搜索教程的研究。谢谢你 –

+0

新增的例子。 :) –

2

由于warrenm说你不应该从主线程(UI线程)不同的线程更新你的UIView。不过,你问是否有任何解决方法。说实话,你应该尝试,而不是阻止第二个线程访问你的方法,理解为什么这些方法被调用两次。这比任何其他问题都更为合理,您应该尝试解决这个问题,而不是尝试快捷方式。

+0

我明白我应该试着去理解为什么这个方法被调用两次,但是我们程序中的错误几乎没有发生,所以我不得不寻找一种以编程方式重现它的方法。无论如何感谢您的建议。我的问题更多的是关于如何阻止2个线程同时访问一个方法,即使它会更新其他变量/对象而不是UI –

+0

在这种情况下,请检查Steven Fisher推荐的内容。 – Peres

相关问题