对象被释放了,它们仍然给出了它们的值。 ARC 未标记(表示关闭)
Posted
技术标签:
【中文标题】对象被释放了,它们仍然给出了它们的值。 ARC 未标记(表示关闭)【英文标题】:Objects were released still they gave their values . ARC were Not mark (means Off) 【发布时间】:2012-12-14 09:57:34 【问题描述】:对象被释放了,但它们仍然给出了它们的值。 ARC 未标记(表示关闭)
-(void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//test of retain and copy
NSString *s1 = [[NSString alloc] initWithString:@"String1"];
NSString *s2 = [s1 copy];
[s1 release];
[s1 release];
[s2 release];
if(s1!=nil)
NSLog(@"11111");
NSArray *array = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil];
[array release];
NSLog(@"S1 - %@ \n S2 - %@ \n Array - %@",s1,s2,array);
===输出===
2012-12-14 15:04:01.165 测试MM[940:207] 11111 2012-12-14 15:04:01.168 testMM[940:207] S1 - String1 S2 - 字符串 1 数组 - S1 - String1 S2 - 字符串 1 数组 -
【问题讨论】:
【参考方案1】:首先,访问已释放的对象是未定义的行为。它可能会访问看起来像原始对象的东西(如果它使用的内存没有被覆盖),或者它可能会访问另一个对象(碰巧稍后被分配),或者它可能会访问随机垃圾(根本不是一个对象) ),否则它可能会崩溃或做其他奇怪的事情。没有办法判断一个对象是否被解除分配,除非你在启动僵尸程序的情况下运行以捕获对解除分配对象的调用。
不仅如此,即使在释放对象上的所有保留后,也无法保证何时释放对象。一个对象在其保留计数变为 0 时被释放。但即使您分配并释放了一个对象,也有可能某些 API 可能已保留然后自动释放它。例如您分配然后立即释放数组,但在initWithObjects:
中它可能会保留并自动释放自身(保留和自动释放对象永远不会不正确),尽管这在init
中不太可能。
特别是在这种情况下,对于字符串,@"String1"
是一个存在于静态内存中的文字字符串,并且像retain
和release
这样的内存管理操作不会做任何事情。 NSString
,当你基于一个常量字符串创建一个新字符串时,只返回那个常量字符串;和 copy
在常量字符串上也返回该常量字符串。所以基本上s1
和s2
都指向静态内存中永远存在的字符串文字。 release
对它们无效。 (但从内存管理规则的角度来看仍然是不正确的。)
array
已分配并释放。这里可能发生的事情(我猜这里,由于上述原因)是数组确实被释放了,但是那部分内存在你打印它的时候并没有被覆盖,因为它的时间太短了。同样,这是未定义的行为。
【讨论】:
以上是关于对象被释放了,它们仍然给出了它们的值。 ARC 未标记(表示关闭)的主要内容,如果未能解决你的问题,请参考以下文章