本文档版权归NickTang所有,没有本人书面或电子邮件允许,不许转载,摘录,发表。多谢!
Objective-C对线程同步和异常处理提供支持,关于异常处理,请参考“Exception Handling.” 你可以使用编译标记-fobjc-exceptions来打开对异常的支持,不过必须是在GCC3.3或以上版本中才能使用。
Objective-C支持多线程。因此会存在两个线程在同一个时间访问同一资源的可能,这是一个很危险的事情。为了让一个线程能一次不受打断的执行完一段代码,Objective-C提供了@synchronized()来阻止上面这样事情的发生。
@synchronized()导致被保护的代码块只能被一个线程执行,其他的线程在试图执行这个代码块的时候会被阻塞,直到当前正在执行这个代码块的线程执行完这个代码块的最后一句话。
@synchronized()可以使用一个Objective-C对象(包括self)来作为参数。这个对象作为信号量使用。它可以锁住一节代码,免得多个线程进入。在程序,你应该使用不同的信号量来锁不同的代码。在程序进入多线程前创建所有的心好了,以避免有争用的情况出现。
Listing 11-1演示了使用self作为信号量来锁住这个实例函数的代码。在稍后的例子中,任何时候只有一个线程执行受保护的代码,因为它使用了但例模式。
使用self对函数加锁
- (void)criticalMethod |
{ |
@synchronized(self) { |
// Critical code. |
... |
} |
} |
一般情况下,我们使用Listing 11-2演示的方式。在获得对互斥资源的访问前,你需要使用获得Account类的信号量,然后对这个信号量加锁。这个信号量一般在Account类的初始化函数中创建。
使用自定义互斥量加锁
Account *account = [Account accountFromString:[accountField stringValue]]; |
|
// Get the semaphore. |
id accountSemaphore = [Account semaphore]; |
|
@synchronized(accountSemaphore) { |
// Critical code. |
... |
} |
Objective-C的同步机制支持回归调用和重入机制。一个线程可以多次对一个信号量加锁;其他的线程会等到这个线程对这个信号量的所有解锁。也就是说,每一个@synchronized()块都正常退出或抛出异常。
当在@synchronized()块中代码抛出了一个异常,Objective-C运行器会捕获这个异常,然后是否这个信号量(以利于受保护资源能被其他线程访问),然后前转者个异常到后继异常处理模块。