0

私は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     
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    }

以下のコマンドでこのコードをビルドしました(ARCオプションなしでビルド)

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

ビルドは警告メッセージなしで成功しました。結果は以下のとおりです。

dealloc!!
myprint!!

この結果について2つの質問があります。

最初の質問は自動解放方法についてです。このコードでは、NSAutoreleasePoolインスタンスなしでautoreleaseメソッドが呼び出されるため、ランタイムエラーが発生すると思います。このコードでランタイムエラーが発生しないのはなぜですか?

2番目の質問はdeallocメソッドについてです。obj2は、deallocメソッドが呼び出された後にmyprintメソッドに応答します。obj2がdeallocメソッドが呼び出された後にmyprintメソッドに応答するのはなぜですか?

ありがとう。

4

3 に答える 3

2

自動解放プールは自動的に作成されると思いますが、それについては間違っている可能性があります。2番目の部分については、リリースはオブジェクトに保持を停止するように指示するため、リリースメッセージの後でいつでも存在することは保証されませんが、そのメモリブロックが次の目的で使用されるまでしばらくは存在する可能性があります。他の何か。基本的にあなたは幸運に恵まれました。コードを何度も実行すると、obj2が毎回myprintに応答するとは限りません。

于 2012-12-06T05:46:04.470 に答える
2

最初の質問は自動解放方法についてです。このコードでは、NSAutoreleasePoolインスタンスなしでautoreleaseメソッドが呼び出されるため、ランタイムエラーが発生すると思います。このコードでランタイムエラーが発生しないのはなぜですか?

自動解放プールがないため、実行時にプールが配置されていないという警告が表示されないことに少し驚いています。エラーではありませんが、リークが発生したことを実行時に警告するだけです。

奇数。私は同じ振る舞いを見ています。お願いします。

2番目の質問はdeallocメソッドについてです。obj2は、deallocメソッドが呼び出された後に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
于 2012-12-06T16:10:40.380 に答える
1

私は同じことを試みました、そしてあなたは何が起こっているかを見ることができます:

ご覧のとおり、自動解放プールはありません...デバッガーにリークが表示されます。

ここに画像の説明を入力してください

編集:

私は調査を行い、リリースが機能していることを知りましたが、システムはリリースに時間がかかり、それまで次の印刷ステートメントが呼び出されます。次のコードで確認できます:

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];
于 2012-12-06T05:48:41.660 に答える