我看了教材里面,所有的@property (nonatomic,retain)xxx的成员,在初始化的时候都是这样写的: NSString *path = [[NSBundle mainBundle]pathForResource:@"sortednames" ofType:@"plist"]; NSDictionary *dict = [[NSDictionary alloc]initWithContentsOfFile:path]; self.names=dict; [dict release]; NSArray *arr = [[names allKeys]sortedArrayUsingSelector:@selector(compare:)]; self.keys = arr; 难道不能写成这样吗: NSString *path = [[NSBundle mainBundle]pathForResource:@"sortednames" ofType:@"plist"]; self.names = [[NSDictionary alloc]initWithContentsOfFile:path]; self.keys = [[names allKeys]sortedArrayUsingSelector:@selector(compare:)]; |
|
20分 |
http://blog.csdn.net/NickTang写成这样会造成内存泄漏的, self.names = [[NSDictionary alloc]initWithContentsOfFile:path];这样的一句话,先执行=后面的部分,申请一块内存,并且内存计数器初始化为1,然后执行=操作,等号操作的左边是self.names,就是调用names的setter函数,而names在声明的时候,使用了retain修饰符,那么在它的setter函数中会对新的内存地址做一次retain,这样就造成这块内存的内存计数器为2,剩下的你自己考虑了。
如果你需要更进一步的资料,请访问我的博客。http://blog.csdn.net/NickTang |
不可以,每次赋值都多分配了一次内存。
self.names = [[NSDictionary alloc]initWithContentsOfFile:path]; 右边[[NSDictionary alloc]initWithContentsOfFile:path]; 会使retainCount+1,这个应该知道,没问题吧。 而在左边的self.names属性的setter内部也多了一次retainCount+1 (属性names的setter方法由编译器运行时生成) 其真实的实现如下: -(void)setnames:(NSString *)names { [_names release]; _names=[names retain]; //这里又多了一次retainCount+1 } 这时的retainCount为2 而我们在使用完属性后都会把属性release一次,这一次只会将引用计数变成了2-1=1 。只要引用计数不为0,这部分的内存永远不会被系统回收,容易造成内存泄露。 |
|
楼主要将self.names拆开来看。
self.names = [[NSDictionary alloc]initWithContentsOfFile:path]; 这写法会造成内存泄露,但是如果后边的表达式是autorelease的就不会有问题。 |
|
2楼 |