实际上我正在处理一个启用了ARC
的项目。我知道使用alloc
和init
正在ownership
对象。我知道,如果我创建一个这样的字符串
NSString *myString = [[NSString alloc]initWithFormat:@"Something"];
那么我需要release
myString
在自己身上。如果我使用启用了 ARC,该怎么办?我不能释放自己。那么它会产生泄漏吗?还是我不应该创建这样的对象?
我也可以创建一个类似于以下代码的字符串。
NSString *myString = [NSString stringWithFormat:@"Something"];
但是我需要将哪种类型完全用于启用 ARC 的项目?如果我使用第一种类型会发生什么?
如果使用 ARC,则编译时将为您添加所有必要的release
调用。它不会泄漏。
两者之间的区别
NSString *myString = [[NSString alloc]initWithFormat:@"Something"];
和
NSString *myString = [NSString stringWithFormat:@"Something"];
是第一个将在该块中最后一次引用myString
后自动释放,而第二个是自动释放的实例,仅在运行循环结束时释放。这不是一个很大的区别,但是如果您使用了很多对象,请尽量避免自动释放的对象以保持较低的内存使用率。
ARC 负责内存管理,所以你不需要担心在 myString
变量上调用 release
,ARC 会为你做到这一点。另外作为建议,我建议使用方便的方法来创建对象,例如
[NSString stringWithFormat:@"Something"];
将字符串指针设置为 nil 就足够了。
你也可以做与没有 ARC 相同的事情,但好处是,如果你不明确地做任何事情,ARC 将为你管理(几乎)一切。
因此,要释放它,您将其设置为 nil,让我们看看您还能做什么:
NSString* str= [[NSString alloc]initWithUTF8String: "Hello"];
// here the retain count of str is 1
__unsafe_unretained NSString* string= str;
// again 1 because string is __unsafe_unretained
void* data= (__bridge_retained void*) string;
// data retains the string, so the retain count is to 2
// This is useful in the case that you have to pass an objective-c object
// through a void pointer.You could also say NSString* data= string;
str=nil;
// Here the retain count of str is 1
NSLog(@"%@",(__bridge NSString*)data);
更新
这就是为什么有时您不会注意到对象被释放的原因:
NSString* str= [[NSString alloc]initWithString: @"hey"];
__unsafe_unretained NSString* str2=str;
str=nil;
NSLog(@"%@",str2);
在这种情况下,str=[[NSString alloc]initWithString: @"hey"] 等于 str=@"hey",区别在于 str 是自动发布的而不是释放的。但是编译器优化了 str=@"hello" 中的代码,所以如果你在自动发布块内,你不会有任何问题,str2 将被正确打印。
这就是我使用 initWithUTF8String 来避免编译器优化的原因。