1

私は最近、Objective C の学習を始めましたが、いくつかの基本的なメモリの問題について混乱しています。たとえば、チュートリアルでこれを見ました:

- (void) setVin: (NSNumber*)newVin {  
    [vin release];  
    vin = [[NSNumber alloc] init];  
    vin = newVin;  
}  

最初に vin にスペースを割り当て、それを newVin に割り当てます。では、vin に新しいスペースを割り当てる意味は何でしょう。割り当てた後、漏れていませんか?

そしてもう一つは

NSString* s1 = [[NSString alloc] init];
NSString* s2 = [[NSString alloc] init];

これら 2 つの文字列のアドレスを出力したところ、これら 2 つのポインターが同じアドレス値を保持していることがわかりました。それらが同じ値(空の文字列だと思います)を保持しているため、コンパイラはそれらを同じアドレスに割り当てることにしましたか?それとも別の問題ですか?

4

2 に答える 2

4

そこには間違いなくメモリリークがあるので、これは非常に悪いチュートリアルです。正しいバリアントは

-(void) setVin: (NSNumber*)newVin {  
    if( newVin != vin ) {
         [vin release];
         vin = [newVin retain];
    }
}

2番目のケースに関しては、NSStringは不変であり、おそらくいくつかの値は内部にキャッシュされます。したがって、保持カウントが増加した同じ値が返されます。

于 2012-12-11T17:50:17.530 に答える
3

最初のサンプルは、ARC 以前のチュートリアルからのものです (つまり、自動参照カウントが無効になっています)。ARC ではrelease、再割り当てを行う必要はありません。

vinARC であろうとなかろうと、このように割り当てる理由はまったくありません。ARC がなければ、それはリークです。ARC では不要な操作です。

2 番目のサンプルは、NSStrings が不変であるという事実を示しています。どちらの呼び出しも空の文字列を作成するため、Cocoa は同じオブジェクトを返しますが、オブジェクトは変更できないことがわかっています。

于 2012-12-11T17:52:52.193 に答える