Memory management of Objective-C 2.0

笑着哭i 提交于 2019-12-25 03:49:29

问题


I'm a beginner in Objective-C. I'm studying memory management in Objective-C by writing simple command line code.

My environment is below.

  • Mac OS X Mountain Lion.
  • Xcode4.5

I wrote a code below.

test.m

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    }

I built this code with below command.(Build with No ARC option)

clang -g -Wall -o main test.m -fno-objc-arc -framework Foundation

The build succeeded with no any warning message. The result was below.

dealloc!!
myprint!!

I have two questions about this result.

First question is about autorelease method. I think this code will raise a runtime error because autorelease method is called with no NSAutoreleasePool instance. why doesn't this code raise a runtime error?

Second question is about dealloc method. obj2 responds to myprint method after dealloc method was called. Why does obj2 respond to myprint method after dealloc method was called?

Thanks.


回答1:


First question is about autorelease method. I think this code will raise a runtime error because autorelease method is called with no NSAutoreleasePool instance. why doesn't this code raise a runtime error?

There is no autorelease pool and, thus, I'm a little surprised you don't see the no pool in place warning when run. It wouldn't be an error, though, just a runtime warning that a leak occurred.

Odd. I'm seeing the same behavior. I'll ask.

Second question is about dealloc method. obj2 responds to myprint method after dealloc method was called. Why does obj2 respond to myprint method after dealloc method was called?

Undefined behavior. obj2 has been deallocated, but deallocation doesn't mean that the memory has been cleared.

If you turn on Malloc Scribble (which scribbles on memory on deallocation), you'll see an expected crash:

env MallocScribble=1 ./main
dealloc!!
Segmentation fault: 11

Better yet, if you turn on zombie detection:

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



回答2:


I believe an autorelease pool is automatically created, but I could be wrong about that one. As for the second part, my understanding is release tells an object to stop being retained and so it is not guaranteed to still exist any time after the release message, but it's possible it will for a while, until that block of memory is used for something else. Essentially you got lucky, and if you run your code many more times, you may not always have obj2 respond to myprint every time.




回答3:


I tried same and you can see what is happening:

As you can see No autorelease pool...leaking is shown in debugger.

EDIT:

I did research, and got to know, that release is working but system is taking time to release till then next print statement is called. You can check with following code :

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];


来源:https://stackoverflow.com/questions/13737571/memory-management-of-objective-c-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!