为什么对象的保留计数会受到“ @synchronized”的影响

时间:2018-12-31 17:33:35

标签: ios automatic-ref-counting synchronized

我发现,在@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_retainAutoreleasedReturnValueobjc_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有效?

0 个答案:

没有答案