リファレンスカウンタが予想と違う挙動をするのですが、なにか?
#import <Foundation/NSObject.h> #import <stdio.h> int main() { id obj = [NSObject alloc]; printf("alloc: %d\n", [obj retainCount]); [obj init]; printf("init: %d\n", [obj retainCount]); [obj retain]; printf("retain: %d\n", [obj retainCount]); [obj retain]; printf("retain: %d\n", [obj retainCount]); [obj release]; printf("release: %d\n", [obj retainCount]); [obj release]; printf("release: %d\n", [obj retainCount]); [obj release]; printf("release: %d\n", [obj retainCount]); // <= ココ return 0; }
以上のソースをref_count_test.mとして保存してコンパイル後に走らせてみます。
すると、
$ cc ref_count_test.m -framework Foundation ref_count_test.m: In function ‘main’: ref_count_test.m:7: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ ref_count_test.m:9: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ ref_count_test.m:11: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ ref_count_test.m:14: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ ref_count_test.m:16: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ ref_count_test.m:18: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ ref_count_test.m:20: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ $ ./a.out alloc: 1 init: 1 retain: 2 retain: 3 release: 2 release: 1 release: 1 $
何事もなく終了。
詳解 Objective-C 2.0によると上記ソースの「ココ」としたところで、
objc: FREED(id): message retainCount sent to freed object=0xXXXXXX
という感じのエラーメッセージが出るとのことですが…
3度目のrelease後もリファレンスカウンタがデクリメントされていないようです。なぜだ!
ちなみに ここ からダウンロードしてきたサンプルコードでも同様な動作でした。むむむ…。
で、もう一度releaseするようにしてみるとエラー。なぜでしょう?よくわかりません><
#import <Foundation/NSObject.h> #import <stdio.h> int main() { id obj = [NSObject alloc]; printf("alloc: %d\n", [obj retainCount]); [obj init]; printf("init: %d\n", [obj retainCount]); [obj retain]; printf("retain: %d\n", [obj retainCount]); [obj retain]; printf("retain: %d\n", [obj retainCount]); [obj release]; printf("release: %d\n", [obj retainCount]); [obj release]; printf("release: %d\n", [obj retainCount]); [obj release]; printf("release: %d\n", [obj retainCount]); [obj release]; return 0; }
$ cc 1.m -framework Foundation 1.m: In function ‘main’: 1.m:7: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ 1.m:9: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ 1.m:11: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ 1.m:14: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ 1.m:16: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ 1.m:18: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ 1.m:18: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘NSUInteger’ $ ./a.out alloc: 1 init: 1 retain: 2 retain: 3 release: 2 release: 1 release: 1 a.out(3707) malloc: *** error for object 0x100108e40: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug Abort trap $