問題:
__unsafe_unretained id
すでにリリースされているオブジェクトを指すポインタがあります。これまでのところ、ポインターをまったく「使用」しない限り(特に、ポインターを介してメソッドを呼び出さない限り)、問題はありません。ただし、メソッドからその値を返そうとすると、戻り値の型が。であることを明示的に指定した場合でも、クラッシュ__unsafe_unretained id
します。何故ですか?を使用すると、 //__unsafe_unretained
のようなメソッドはまったく呼び出されないと思いましたか?私はそれが(単純なネイティブの割り当てのみを行うことを意味する)であるかのようにほとんど使用できると思いましたか?retain
release
autorelease
__unsafe_unretained id
void*
環境:
- で開発
Xcode 4.4.1
- 使用する
iOS SDK 5.1
ARC
はenabled
iPhone 4.3 / 5.0 / 5.1 Simulator
またはで実行iPhone 4.3 Device
- 両方でクラッシュし
Debug
、Release
ビルドします
ソースコード:
// Declare my class with 1 member.
@interface MyClass : NSObject
{
__unsafe_unretained id m_MyMember;
}
@end
// **************************************************************************************************** //
// Implement my class.
@implementation MyClass
// Setter
-(void)SetMember:(__unsafe_unretained id)member
{
m_MyMember = member;
}
// Getter: by passing parameter by reference
-(void)GetMember1:(__unsafe_unretained id*)member
{
*member = m_MyMember; // No problem.
}
// Getter: by return value
-(__unsafe_unretained id)GetMember2
{
return m_MyMember; // Crashed in here!
}
@end
// **************************************************************************************************** //
//! Application entry point.
int main(int argc, char *argv[])
{
@autoreleasepool
{
{
// Create an object that dies immediately. deadObj is a dangling pointer.
__unsafe_unretained id deadObj = [[NSMutableString alloc] initWithFormat:@"%d", 12];
// Create my object.
MyClass* myObject = [[MyClass alloc] init];
// Assign my member.
[myObject SetMember:deadObj];
// Get back my member: by passing parameter by reference
__unsafe_unretained id unsafePointer1;
[myObject GetMember1:&unsafePointer1]; // No problem.
// Get back my member: by return value
__unsafe_unretained id unsafePointer2;
unsafePointer2 = [myObject GetMember2]; // Crashed in here!
int BreakpointHere = 0;
}
}
}
コールスタック(iPhone 4.3 Simulator / iOS 4.3デバイス):
#0 0x011db09b in objc_msgSend ()
#1 0x00106712 in __arclite_objc_retainAutoreleaseReturnValue at /SourceCache/arclite_host/arclite-29.1/source/arclite.m:259
#2 0x00001fec in -[MyClass GetMember2] at /Users/user/SourceCode/main.m:28
#3 0x00002147 in main at /Users/user/SourceCode/main.m:56
コールスタック(iPhone 5.0 / 5.1シミュレーター):
#0 0x014f6d25 in objc_retain ()
#1 0x014f7fe3 in objc_retainAutoreleaseReturnValue ()
#2 0x00001fec in -[MyClass GetMember2] at /Users/user/SourceCode/main.m:28
#3 0x00002147 in main at /Users/user/SourceCode/main.m:56