微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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始终会保留该对象.即使稍后从数组中删除对象,这也可以保证其生命周期.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐