问题描述
刚学objective c,遇到内存管理问题,情景是这样的:启用了arc,设定了一个Person类,只有一个weak的property,(NSMutableArray *)favor
Person.h如下
#import <Foundation/Foundation.h>@interface Person : NSObject@property (nonatomic, weak) NSMutableArray *favor;@end
Person.m如下
#import 'Person.h'@implementation Person- (void)dealloc { NSLog(@'Person dealloc!');}@end
main.m如下
#import <Foundation/Foundation.h>#import 'Person.h'int main(int argc, char * argv[]) { Person *p = [[Person alloc] init]; NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@'1', @'2', nil]; p.favor = arr; NSLog(@'%@', p.favor); arr = nil; NSLog(@'%@', p.favor);}
控制台打印的结果是这样的
2015-09-11 13:31:14.408 Prog1[32787:193921] ( 1, 2)2015-09-11 13:31:14.409 Prog1[32787:193921] ( 1, 2)2015-09-11 13:31:14.409 Prog1[32787:193921] Person dealloc!
我的分析是:arr刚开始指向的对象只有arr一个强指针指向它,虽然p.favor = arr,但favor属性是weak的,那么当arr = nil时,这个对象就没有强指针指向它了,此时该对象应该被释放,但是第二次打印的结果表明并没有被释放再但是,当我注释掉第一次的打印,即
#import <Foundation/Foundation.h>#import 'Person.h'int main(int argc, char * argv[]) { Person *p = [[Person alloc] init]; NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@'1', @'2', nil]; p.favor = arr;// NSLog(@'%@', p.favor); arr = nil; NSLog(@'%@', p.favor);}
打印结果却是
2015-09-11 13:44:48.956 Prog1[36117:210004] (null)2015-09-11 13:44:48.958 Prog1[36117:210004] Person dealloc!
即表明对象被释放了
我的问题是:
启用了arc后,对象在没有强指针(强引用)的情况下是否被立即释放?如果不是,是什么时候释放?(注意我用init开头的方法创建的数组对象,在非arc情况下是不会autorelease的,main函数中我也没有@autoreleasepool)
点语法是否会影响对象释放?(我提这个问题的原因是,当我不用property而是把favor设为@public的成员变量时,用p->_favor打印第一次就不会出现arr = nil后没有被释放的情况)
arc到底是怎样决定何时释放对象的呀?我知道arc是编译时就决定了何时release retain autorelease,那它是怎么决定的呢?
问题解答
回答1:#import <Foundation/Foundation.h>#import 'Person.h'int main(int argc, char * argv[]) { // 这里的p是什么引用 默认必须是强引用 ARC会在当前函数栈 结束时 做RetainCount-1 Person *p = [[Person alloc] init]; // 同理的arr是强引用 所以 后面的代码 同样不会有问题 跟你weak不weak没关系 NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@'1', @'2', nil]; p.favor = arr; NSLog(@'%@', p.favor); arr = nil; NSLog(@'%@', p.favor);}
具体的问题 好好读读这个http://clang.llvm.org/docs/AutomaticReferenceCounting.html读完你就全明白了 内存管理就这点事儿
回答2:当该内存空间没有指针指向它了,它就被自动释放了。
p.favor = arr; arr = nil;
arr是强引用,已经被置nil了,p.favor自然也就找不到相应内存地址了,所以输出(null)。