我发现,在@synchronized
块内创建的对象的保留计数与在@synchronized
块外创建的对象的保留计数不同。
情况1:在@synchronized
块中创建,观察者的保留计数为2:
- (NSUInteger)mv_observeKeyPath:(NSString *)keyPath
withBlock:(MVKVOBlock)block
options:(NSKeyValueObservingOptions)options {
@synchronized (lock) {
MVKVOProxy *observer = [MVKVOProxy observerWithTarget:self keyPath:keyPath block:block];
// po [observer performSelector:@selector(retainCount)] is 2
[self addObserver:observer forKeyPath:keyPath options:options context:NULL];
return observer.observerID;
}
}
情况2:在@synchronized
块之外创建,观察者的保留计数为1:
- (NSUInteger)mv_observeKeyPath:(NSString *)keyPath
withBlock:(MVKVOBlock)block
options:(NSKeyValueObservingOptions)options {
MVKVOProxy *observer = [MVKVOProxy observerWithTarget:self keyPath:keyPath block:block];
@synchronized (lock) {
// po [observer performSelector:@selector(retainCount)] is 1
[self addObserver:observer forKeyPath:keyPath options:options context:NULL];
return observer.observerID;
}
}
我知道通过方法返回的对象将被objc_retainAutoreleasedReturnValue
和objc_autoreleaseReturnValue
包装。它用于优化以消除无用的函数调用,例如[[obj autorelase] retain]
。
objc_retainAutoreleasedReturnValue
的方法定义为:
id objc_retainAutoreleasedReturnValue(id obj)
{
if (acceptOptimizedReturn() == ReturnAtPlus1) return obj;
return objc_retain(obj);
}
我调试并进入汇编代码,发现只有在情况2中,objc_retain
才会被调用。
方法objc_autoreleaseReturnValue
是:
id objc_autoreleaseReturnValue(id obj)
{
if (prepareOptimizedReturn(ReturnAtPlus1)) return obj;
return objc_autorelease(obj);
}
在两种情况下,都会调用objc_autorelease
。
因此,在情况1中,方法调用堆栈为[[observer autorelaase] retain]
,在情况2中,方法调用堆栈为[observer autorelaase]
。
不奇怪吗?为什么@synchronized
对ARC有效?