objective-c の autorelease の動き

C# のガベージコレクションと同じなのかなぁ、と思ったけど、動き的には c++ のスマートポインタに近いのかな。
autorelease を指定すると、NSAutoreleasePool のオブジェクトに溜め込まれるようです。ここで、間違って release してしまうと落ちてしまう(core dump)ので、alloc と release の対応は、malloc/free, new/delete 並に厳しいコーディングをしないと駄目ですね。
一律、autorelease を使って release を使わないで記述するか、autorelease を使わずに release 自体をまめにコーディングしていくか悩むところ。

UIImage のように大きめなメモリを取得するものは、autorelease にするとメモリを占有してしまうので、release をするってのが適当ですね。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
export INCLUDE=/GNUstep/System/Library/Headers
export LIB=/GNUstep/System/Library/Libraries
export CFLAGS='-fconstant-string-class=NSConstantString  -enable-auto-import'
 
gcc -o main main.m -lobjc -lgnustep-base -I $INCLUDE -L $LIB $CFLAGS
*/
#import <stdio.h>
#import <Foundation/Foundation.h>
#import <Foundation/NSObject.h>
 
@interface Hello: NSObject
{
    @private
    NSString *_msg ;
}
@end
 
@implementation Hello
- (void)setMessage:(NSString*)msg
{
    _msg = msg;
}
- (void)print
{
    // NSLog( _msg );
    printf("%s\n", [_msg cString]);
}
- (void)dealloc
{
    NSLog( @"in dealloc" );
    [super dealloc];
}
@end
 
int _main(int argc, char *argv[])
{
    puts("hello obj-c world.");
 
    // autorelease を使った場合
    Hello *hello = [[[Hello alloc] init] autorelease];
    [hello setMessage:@"hello objective-c in hello class"];
    [hello print];
     
    // autorelease を使わない場合
    Hello *hello2 = [[Hello alloc] init];
    [hello2 setMessage:@"hello objective-c no autorelease"];
    [hello2 print];
    [hello2 release];
     
    return 0;
}
 
int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int retVal = _main(argc, argv);
    NSLog(@"before pool release");
    [pool release];    // ここで一気に解放される
    NSLog(@"after pool release");
    return retVal;
}

実行結果

1
2
3
4
5
6
7
8
$ main
hello obj-c world.
hello objective-c in hello class
hello objective-c no autorelease
2011-07-05 15:46:23.484 main[4124] in dealloc
2011-07-05 15:46:23.545 main[4124] before pool release
2011-07-05 15:46:23.545 main[4124] in dealloc
2011-07-05 15:46:23.545 main[4124] after pool release
カテゴリー: 開発, Objective-C パーマリンク