ios – ARC的线程安全设计

首先让我引用Apple Threading Programming Guide的一章:

Be Aware of Threats to Code Correctness

When using locks and memory barriers,you should always give careful thought to their
placement in your code. Even locks that seem well placed can actually
lull you into a false sense of security. The following series of
examples attempt to illustrate this problem by pointing out the flaws
in seemingly innocuous code. The basic premise is that you have a
mutable array containing a set of immutable objects. Suppose you want
to invoke a method of the first object in the array. You might do so
using the following code:

NSLock* arrayLock = GetArrayLock();
NSMutableArray* myArray = GetSharedArray();
id anObject;

[arrayLock lock];
anObject = [myArray objectAtIndex:0];
[arrayLock unlock];

[anObject doSomething];

Because the array is mutable,the lock around the array prevents other
threads from modifying the array until you get the desired object. And
because the object you retrieve is itself immutable,a lock is not
needed around the call to the doSomething method.

There is a problem with the preceding example,though. What happens if
you release the lock and another thread comes in and removes all
objects from the array before you have a chance to execute the
doSomething method? In an application without garbage collection,the
object your code is holding Could be released,leaving anObject
pointing to an invalid memory address. To fix the problem,you might
decide to simply rearrange your existing code and release the lock
after your call to doSomething,as shown here:

NSLock* arrayLock = GetArrayLock();
NSMutableArray* myArray = GetSharedArray();
id anObject;

[arrayLock lock];
anObject = [myArray objectAtIndex:0];
[anObject doSomething];
[arrayLock unlock];

By moving the doSomething call inside the lock,your code guarantees
that the object is still valid when the method is called.
Unfortunately,if the doSomething method takes a long time to execute,
this Could cause your code to hold the lock for a long time,which
Could create a performance bottleneck.

The problem with the code is not that the critical region was poorly
defined,but that the actual problem was not understood. The real
problem is a memory management issue that is triggered only by the
presence of other threads. Because it can be released by another
thread,a better solution would be to retain anObject before releasing
the lock. This solution addresses the real problem of the object being
released and does so without introducing a potential performance
penalty.

NSLock* arrayLock = GetArrayLock();
NSMutableArray* myArray = GetSharedArray();
id anObject;

[arrayLock lock];
anObject = [myArray objectAtIndex:0];
[anObject retain];
[arrayLock unlock];

[anObject doSomething];
[anObject release];

问题是:使用ARC时有什么方法可以解决问题吗?

解决方法

ARC自动为您解决此问题;认情况下,每个指针都是一个强指针,这意味着在完成使用该指针之前,保证保留该对象.

这意味着无论何时从数组中获取对象,ARC始终会保留该对象.即使稍后从数组中删除对象,这也可以保证其生命周期.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...