案例 1 和案例 2 是等价的。可以这样想:
情况1:
-(void)func {
NSString *name = someObject; // Retain, so +1 on the reference count
self.userName = name; // Retain, so +1 on the reference count
// End of function, name is going out of scope,
// so release name, so -1 on the reference count.
// Total change to the reference count: +1 for self.userName.
}
案例二:
-(void)func {
self.userName = someObject; // Retain, so +1 on the reference count
// End of function.
// Total change to the reference count: +1 for self.userName.
}
所以他们的工作是一样的。请注意,如果这样做是安全的,则允许编译器取消保留和释放对。在像这样的简单情况下,它肯定会忽略它们。考虑对引用计数的所有 +1 和 -1 更改只是为了使其更清晰。
要回答有关 __bridge 与 __bridge_transfer 的问题:您调用ABRecordCopyCompositeName
了 ,它返回对非托管对象 (a CFStringRef
) 的引用。函数名中的Copy
告诉你这个对象现在归你所有,你最终需要释放它。
您可以致电 来完成此操作CFRelease
,也可以让 ARC 为您完成此操作。 __bridge
告诉 ARC 它不允许拥有所有权(换句话说,您想手动释放该对象,或者它不归您所有)。 __bridge_transfer
告诉 ARC 它应该获得所有权并在完整表达式的末尾释放对象(换句话说,您要求 ARC 为您进行释放)。
与__bridge_transfer
:
self.userName = (__bridge_transfer NSString *)ABRecordCopyCompositeName(person); // +1 inside ABRecordCopyCompositeName, +1 for self.userName, -1 at the end, because of the __bridge_transfer.
// self.userName now is the only strong reference. Good.
与__bridge
:
CFStringRef userName = ABRecordCopyCompositeName(person); // +1 inside ABRecordCopyCompositeName.
self.userName = (__bridge NSString *)userName; // +1 for self.userName, ARC does nothing because of the __bridge.
CFRelease(userName); // -1.
// self.userName now is the only strong reference. Good.
有__bridge
和内存泄漏:
self.userName = (__bridge NSString *)ABRecordCopyCompositeName(person); // +1 inside ABRecordCopyCompositeName, +1 for self.userName, ARC does nothing because of the __bridge.
// self.userName now is one strong reference, but reference count is 2.
// Memory leak.