tom*_*tom 3 memory-leaks memory-management nsstring ios
当不在ARC下时,对于以下代码,
.H
@property (nonatomic, retain) NSString *s;
Run Code Online (Sandbox Code Playgroud)
.M
NSString *m = [NSString stringWithString:@"Hellow, World"];
s = [m retain];
// later on
s = nil; <-- will this release the ref count on the string and hence get the string released?
Run Code Online (Sandbox Code Playgroud)
小智 7
当像这样使用时(即通过直接访问实例变量),那么不,它不会.但是,如果您使用属性的访问器方法([self setS:nil];或self.s = nil;),那么是的,它会.
另请注意,释放对象并释放其内存是两件完全不同的事情.仅当对象没有更强的引用时才释放对象 - 即您最后引用它然后释放它.如果你释放它但它有其他引用(通过先前保留),那么它将不会被释放,只有它的引用计数将减1.
此外,如果你有一个保留属性,例如你的例子中的那个,你不能做1.直接访问底层实例变量,2.做类似的东西
NSString *m = [NSString stringWithString:@"Hellow, World"];
s = [m retain];
Run Code Online (Sandbox Code Playgroud)
为什么?因为第一行根本就没必要 - 真的,为什么- [NSString stringWithString:]?你正在创建一个常量字符串,然后创建它的精确副本 - 它只是多余的.如果Cocoa的设计师是新手,这条线也会浪费内存 - 同一个不可变字符串的两个精确副本.幸运的是,任何实现NSString的人都为这种情况做好了准备,并使这个方法检查它的参数是一个常量并返回它而不做任何事情,如果是 - 所以你得到了相同的指针,但是有一些额外的调用objc_msgSend- 这不是你要.
第二行也是错误的 - 再次,你不按原样使用支持ivar.此外,声明属性retain的原因是 - 如果将对象设置为属性,则该对象将由setter方法保留 - 无需手动保留它.
总而言之,你最好写
self.s = @"Hello World";
// ...
self.s = nil;
Run Code Online (Sandbox Code Playgroud)
代替.
| 归档时间: |
|
| 查看次数: |
1455 次 |
| 最近记录: |