問題:返回__unsafe_unretained指針在目標C釋放的對象導致崩潰
我有一個__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模擬器/的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
獲得的經驗教訓: 1.始終__nil__指針死前的__unsafe_unretained指針。 2.使用'__weak'代替(需要iOS 5運行時)。 – Pang