2013-05-01 2 views
4

Вот мой код:Почему переменная с квалификатором __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 стал равен нулю.

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; 
} 

Может кто-нибудь объяснить мне, почему он работает таким образом?

ответ

5

Кажется, что [[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] не может вернуть общий экземпляр.

+0

Martin R, да, все неизменяемые классы возвращают «общий экземпляр» (проверили NSString, NSDictionary и т. Д.), Но есть ли способ передать эту «функцию»? – AndrewShmig

+2

@AndrewShmig: Чего вы пытаетесь достичь? Почему вам нужна слабая ссылка, чтобы стать нулевой? –

+0

Martin R, я пытаюсь понять, ПОЧЕМУ __weak не работает, поскольку ожидается, что он будет работать после того, как переменная obj покинет свой объем. – AndrewShmig

Смежные вопросы