为什么带有__weak限定符的变量会保留一个对象?

这是我的代码:

extern void _objc_autoreleasePoolPrint(); int main(int argc, const char * argv[]) { NSArray __weak *tmp = nil; @autoreleasepool { NSArray __strong *obj = [[NSArray alloc] init]; NSLog(@"obj &: %p", obj); tmp = obj; NSLog(@"tmp &: %p", tmp); _objc_autoreleasePoolPrint(); } NSLog(@"tmp: %@", tmp); // why not (null) ? return 0; } 

和控制台输出:

  2013-05-01 22:14:32.966 SimpleConsoleObjectiveCApplicationWithARC[40660:f07] obj &: 0x7fedf9403110 2013-05-01 22:14:32.969 SimpleConsoleObjectiveCApplicationWithARC[40660:f07] tmp &: 0x7fedf9403110 objc[40660]: ############## objc[40660]: AUTORELEASE POOLS for thread 0x7fff751af180 objc[40660]: 2 releases pending. objc[40660]: [0x7fedf9805000] ................ PAGE (hot) (cold) objc[40660]: [0x7fedf9805038] ################ POOL 0x7fedf9805038 objc[40660]: [0x7fedf9805040] 0x7fedf9403110 __NSArrayI objc[40660]: ############## 2013-05-01 22:14:32.971 SimpleConsoleObjectiveCApplicationWithARC[40660:f07] tmp: ( ) 

PS#1

将NSArray更改为NSMutableArray并将tmp变量设置为nil。

 extern void _objc_autoreleasePoolPrint(); int main(int argc, const char * argv[]) { NSMutableArray __weak *tmp = nil; @autoreleasepool { NSMutableArray __strong *obj = [[NSMutableArray alloc] init]; NSLog(@"obj &: %p", obj); tmp = obj; NSLog(@"tmp &: %p", tmp); _objc_autoreleasePoolPrint(); } NSLog(@"tmp: %@", tmp); return 0; } 

有人能解释一下为什么它会这样运作吗?

似乎[[NSArray alloc] init]返回空NSArray的“共享实例”:

 NSArray *a = [[NSArray alloc] init]; NSArray *b = [[NSArray alloc] init]; NSLog(@"a &: %p", a); NSLog(@"b &: %p", b); 

输出:

     a&:0x100103110
     b&:0x100103110

即使您的强引用obj消失,此“共享实例”仍然存在,因此弱指针未设置为nil

显然, [[NSMutableArray alloc] init]不能返回共享实例。