Objective-C2.0的内存管理
我是Objective-C的初学者。 我正在通过编写简单的命令行代码来学习Objective-C中的内存管理 我的环境在下面Objective-C2.0的内存管理,objective-c,ios,macos,cocoa,foundation,Objective C,Ios,Macos,Cocoa,Foundation,我是Objective-C的初学者。 我正在通过编写简单的命令行代码来学习Objective-C中的内存管理 我的环境在下面 MacOSX山狮 Xcode4.5 我在下面写了一段代码 test.m 1 #import <Foundation/Foundation.h> 2 #import <stdio.h> 3 4 @interface A : NSObject 5 -(void)myprint; 6 @end 7
- MacOSX山狮
- Xcode4.5
1 #import <Foundation/Foundation.h>
2 #import <stdio.h>
3
4 @interface A : NSObject
5 -(void)myprint;
6 @end
7
8 @implementation A
9 -(void)dealloc {
10 printf("dealloc!!\n");
11 [super dealloc];
12 }
13
14 -(void)myprint {
15 printf("myprint!!\n");
16 }
17 @end
18
19 int main(void) {
20
21 id obj1 = [[[NSObject alloc] init] autorelease];
22 id obj2 = [[A alloc] init];
23
24 [obj2 release];
25 [obj2 myprint];
26
27 return 0;
28 }
生成成功,但没有任何警告消息。
结果如下
dealloc!!
myprint!!
关于这个结果,我有两个问题
第一个问题是关于自动释放方法。
我认为这段代码会引发运行时错误,因为
在没有NSAutoreleasePool实例的情况下调用autorelease方法。
为什么这段代码不引发运行时错误
第二个问题是关于dealoc方法。
调用dealloc方法后,obj2响应myprint方法。
为什么在调用dealloc方法后,obj2会响应myprint方法
谢谢。我相信自动释放池是自动创建的,但我可能错了。至于第二部分,我的理解是释放告诉一个对象停止被保留,因此不能保证它在释放消息之后的任何时候仍然存在,但它可能会存在一段时间,直到那个内存块被用于其他东西。实际上,您很幸运,如果您多次运行代码,您可能不会每次都让obj2响应myprint。我相信自动释放池是自动创建的,但我可能错了。至于第二部分,我的理解是释放告诉一个对象停止被保留,因此不能保证它在释放消息之后的任何时候仍然存在,但它可能会存在一段时间,直到那个内存块被用于其他东西。基本上,您很幸运,如果您多次运行代码,您可能不会每次都让obj2响应myprint。我也尝试过,您可以看到发生了什么: 正如您所看到的,没有自动释放池…泄漏显示在调试器中 编辑: 我做了研究,了解到,这个版本正在运行,但系统需要时间发布,直到调用下一个打印声明。您可以使用以下代码进行检查:
A *obj2 = [[A alloc] init];
NSLog(@"1rc=%ld",[obj2 retainCount]);
[obj2 release];
for (long i=0; i<1000000; i++) {
for (long j=0; j<10000; j++) {
;
}
}
[obj2 myprint];
for (long i=0; i<1000000; i++) {
for (long j=0; j<10; j++) {
;
}
}
NSLog(@"myprint again");
[obj2 myprint];
A*obj2=[[A alloc]init];
NSLog(@“1rc=%ld”,[obj2重新计数];
[obj2释放];
(长时间i=0;i我尝试了相同的方法,您可以看到发生了什么:
正如您所看到的,没有自动释放池…泄漏显示在调试器中
编辑:
我做了研究,了解到该版本正在运行,但系统需要时间发布,直到调用下一个打印语句。您可以使用以下代码进行检查:
A *obj2 = [[A alloc] init];
NSLog(@"1rc=%ld",[obj2 retainCount]);
[obj2 release];
for (long i=0; i<1000000; i++) {
for (long j=0; j<10000; j++) {
;
}
}
[obj2 myprint];
for (long i=0; i<1000000; i++) {
for (long j=0; j<10; j++) {
;
}
}
NSLog(@"myprint again");
[obj2 myprint];
A*obj2=[[A alloc]init];
NSLog(@“1rc=%ld”,[obj2重新计数];
[obj2释放];
对于(长i=0;i
第一个问题是关于自动释放方法。我想这段代码会
引发运行时错误,因为调用autorelease方法时没有
NSAutoreleasePool实例。为什么这段代码不引发运行时
错误
没有自动释放池,因此,我有点惊讶,您在运行时没有看到“无池到位”警告。不过,这不会是一个错误,只是一个发生泄漏的运行时警告
奇怪。我看到了同样的行为。我会问的
第二个问题是关于dealoc方法的。obj2响应myprint
方法。为什么obj2会响应
调用dealloc方法后的myprint方法
未定义的行为。obj2
已解除分配,但解除分配并不意味着内存已被清除
如果启用Malloc Scribble(在释放时在内存上涂鸦),您将看到预期的崩溃:
env MallocScribble=1 ./main
dealloc!!
Segmentation fault: 11
更好的是,如果启用僵尸检测:
env NSZombieEnabled=YES ./main
dealloc!!
2012-12-06 08:10:14.580 main[80114:f07] *** -[A myprint]: message sent to deallocated instance 0x7f9b7ac09dd0
Trace/BPT trap: 5
第一个问题是关于自动释放方法。我想这段代码会
引发运行时错误,因为调用autorelease方法时没有
NSAutoreleasePool实例。为什么这段代码不引发运行时
错误
没有自动释放池,因此,我有点惊讶,您在运行时没有看到“无池到位”警告。不过,这不会是一个错误,只是一个发生泄漏的运行时警告
奇怪。我看到了同样的行为。我会问的
第二个问题是关于dealoc方法的。obj2响应myprint
方法。为什么obj2会响应
调用dealloc方法后的myprint方法
未定义的行为。obj2
已解除分配,但解除分配并不意味着内存已被清除
如果启用Malloc Scribble(在释放时在内存上涂鸦),您将看到预期的崩溃:
env MallocScribble=1 ./main
dealloc!!
Segmentation fault: 11
更好的是,如果启用僵尸检测:
env NSZombieEnabled=YES ./main
dealloc!!
2012-12-06 08:10:14.580 main[80114:f07] *** -[A myprint]: message sent to deallocated instance 0x7f9b7ac09dd0
Trace/BPT trap: 5
否…未创建自动释放池。正如您在我的回答中看到的附加图像。在这种情况下,没有自动释放池。您的回答的其余部分几乎是正确的;对象已解除分配,但解除分配并不意味着立即重用字节。打开僵尸,您将得到一个错误。否…未创建自动释放池。如您所见在我的答案中附加了图像。在这种情况下没有自动释放池。你的答案的其余部分几乎是正确的;对象已被释放,但释放并不意味着字节立即被重用。打开僵尸,你会得到一个错误。循环的那些没有意义。没有线程?完全线性执行,包括释放和取消分配对象。你从未定义的行为中得出了错误的结论。我陷入了这个困境,甚至我问了几十个cocoa资源(同事)没有人能给出一个很好的理由。因此,这终于结束了。这个问题仍然悬而未决。这确实是一个值得学习的好问题。我正在等待更正,并提供证据。我用Xcode尝试了相同的代码。没有出现关于自动释放的警告消息。但我明白,在没有池的情况下调用自动释放方法将导致oke内存泄漏。令人惊讶……正如您在所附的屏幕截图中看到的那样,它确实出现了:@我怀疑这可能是命令行问题;该应用程序执行速度如此之快,以至于mechan