ケース 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.
}
ケース 2:
-(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.