为什么不崩溃?

时间:2012-03-25 14:19:49

标签: objective-c memory-management

为什么这段代码有效:

NSNumber *a = [[NSNumber alloc] initWithInt:5];
[a release];

NSLog(@"%i", [a intValue]);// it shows 5. why???

消息intValue被发送到解除分配的对象。它的引用计数必须为0.发生了什么事?

3 个答案:

答案 0 :(得分:2)

释放指针只是告诉操作系统内存管理器内存不再使用 - 对象所在的内存块实际上不会被更改。

但是,由于现在这是“死”的内存,以后的分配可能会重新使用该内存块。

如果您通过在发布版本和日志值之间添加其他分配来进行实验,那么您应该能够看到这种情况发生。

答案 1 :(得分:2)

我认为NSNumber有一个特殊的实现,就像NSString一样。

[NSNumber alloc]实际上并不分配内存,而是返回一个通用指针。分配将由其中一个init方法处理,但这里同样是initWithInt:5是一种常见的情况,它不是创建一个新对象,而是返回一个指向默认对象的指针。无论如何这个都不能发布。

// do it once
NSNumber* five1 = [NSNumber alloc];
NSLog(@"%p", five1);
five1 = [five1 initWithInt:5];
NSLog(@"%p", five1);

// and once more
NSNumber* five2 = [NSNumber alloc];
NSLog(@"%p", five2);
five2 = [five2 initWithInt:5];
NSLog(@"%p", five2);

事实上,发送多次发布消息应该没有问题:

[five1 release];
[five1 release];
[five1 release];

答案 2 :(得分:0)

我想如果你将'a'设置为nil就行不通,但只要它指向堆中的某个位置并且那里有一个5整数,你就得到那个5.但是如果你之间做了什么在发布和NSLog中,您可能会得到不同的结果(任何类型的垃圾)。