为什么这段代码有效:
NSNumber *a = [[NSNumber alloc] initWithInt:5];
[a release];
NSLog(@"%i", [a intValue]);// it shows 5. why???
消息intValue
被发送到解除分配的对象。它的引用计数必须为0.发生了什么事?
答案 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中,您可能会得到不同的结果(任何类型的垃圾)。