2012-01-24 8 views
0

は、私たちは以下のように見えるいくつかのコードを持っているとしましょう:私はプロパティを保持するように設定しましたが、autoreleaseに設定されていても解放するはずですか?

@interface SomeClass : NSObject 
@property (nonatomic, retain) NSString *someString; 
@end 

@implementation SomeClass 
@synthesize someString; 
-(id)init { 
    if (self=[super init]) { 
     someString = [NSString stringWithString:@"some string"]; 
    } 
    return self; 
} 
@end 

私はsomeStringが自動解放するように設定した場合でも、SomeClassのdeallocメソッドでsomeStringプロパティをリリースすることになって、私は実際にそれを保持することはありませんアム私のinit方法?その場合は、-releaseメソッドで[super dealloc]の前に[someString release]を追加するだけです。正しい?

今私が抱えている問題は、Cocos2Dを使用しているときに矛盾する状況に遭遇したことです。

@interface SomeLayer : CCLayer 
@property (nonatomic, retain) CCSprite *someSprite; 
@end 

@implementation SomeLayer 
@synthesize someSprite; 
-(id)init { 
    if (self=[super init]) { 
     someSprite = [CCSprite spriteWithFile:@"SomeFile.png"]; 
     [self addChild:someSprite]; 
    } 
    return self; 
} 
@end 

は今、私は私の層SomeLayerに子としてsomeSpriteを追加しました:私のコードは次のようになります。だから、私はここにメモリリークがないことを確認するために何をすべきですか?私は、次のものを考えることができます:

  1. もちろん、私はSomeLayerさん-dealloc方法で[someSprite release]を呼び出すと思うだろう。それはを[super dealloc](次の行)に与えます。私は子供を削除していないため、スーパークラスは今リリースしたばかりの子供にアクセスしようとしています。
  2. -deallocメソッドで[self removeChild:someSprite cleanup:YES]メソッドを呼び出すと、子を削除して解放します。だから私は[someSprite release]とフォローアップする必要はありません。しかし、ねえ、-deallocスーパークラスCCNodeのメソッドはすでに私のためにすべてを行います。
  3. 私は何もしません。私は-deallocメソッドをオーバーライドしません。これはうまくいくようですが、「あなたが何かを保持していれば、それを解放するはずです」と声明と矛盾しています。

なぜ私はケースIでオブジェクトをリリースしなければならないかについての助けと、初期段階のケースIIで、長期間に渡って多くのメモリ関連の問題を軽減するのに役立つ。

おかげ

答えて

3
someString = [NSString stringWithString:@"some string"]; 

これは間違っています。間もなく消える自動リリースオブジェクトへのポインタを保持していて、someStringポインタを使用しようとすると悪いことが起こります。アクセサ([self setSomeString:…])を使用し、自動解放された値(someString = [… retain])を保持するか、保持された値(someString = [[NSString alloc] init…])を返すメソッドを使用する必要があります。

実際の使用例では、スプライトを同じにする必要があります。がスプライトを過剰にリリースしたため、値を保持せずにreleaseを呼び出します。 Cocoa Memory Management Guideを読むと、長期的には多くのトラブルを回避できます。

ところで、あなたの主な問題は、someString変数への単純な割り当てが割り当てられた値を保持していると思うことだと思います。それは事実ではありません(より正確には、ARCなしではありません)。インスタンス変数への代入は単なる代入です。アクセサーを通過する場合は、メッセージ([self setSomeString:…])を送信するか、ドット表記(self.someString = …)を使用する必要があります。

+0

再び良いだろう。基本的な '@ synthesize'コードは私のためのプロパティを保持し、' -dealloc'メソッドで解放することができます。 Good to go :) – Himanshu

1

明示的に割り当てるオブジェクトを解放するだけです。あなたが与えた例はどれも割り当てられていないので、オートレリースされています。オートレリースされたオブジェクトを長時間保持したい場合は、それを保持する必要があります。オブジェクトを解放する必要があります。あなたはプロパティを持っている場合

また、あなたはあなたが本当にメモリManagement Programming Guideを読む必要がviewDidUnload

self.someString = nil;

+0

メモリ管理については、過度に単純化するのは危険であるため、非常に注意する必要があります。あなたが割り当てたものを解放しなければならないというのは本当ではありません。ルールに合わないコピーは少なくともあります。 – zoul

+0

@zoul私が聞いたルールはNARC - New、Alloc、Retain、Cop​​yで要約されています。あなたが使用しているものは、明示的にリリースされたり、自動リリースされたりする必要があります。しわは 'self.'アクセサーの「隠された」保持です。 – Maple

1

にnilにそれらを設定する必要があります。


あなたが保持して使用してオブジェクトの所有権を取得できる4つのルール

  • の2があります。
  • あなたはもはやあなたがretainとしてプロパティを宣言するとき、あなたは適切な変数にreleaseを呼び出す必要がありますが

を所有しているオブジェクトの所有権を放棄しなければならない、それを必要とします。あなたのケースでは、あなたのdeallocは

- (void)dealloc 
    [someSprite release]; 
    [super dealloc]; 
} 

そして、あなたが新たに作成されたスプライト

someSprite = [[CCSprite spriteWithFile:@"SomeFile.png"] retain]; 
0
@synthesize someSprite; 

これを保持する必要があるこの問題を回避するには、このコード

if (self=[super init]) { 
     someSprite = [CCSprite spriteWithFile:@"SomeFile.png"]; // here you assign pointer to new object 
     [self addChild:someSprite]; // all right, you can use newly created object in this scope 
    } 
// but here that object can be deleted from memory and someSprite can points to nothing 

をご覧に見えるはずですlineはSomeSpriteの保持カウントを1にする。dealloあなたはそれを解放するので、保持は0に戻ります。オブジェクトの解放。その両方が今等しい

[CCSprite spriteWithFile:@"SomeFile.png"]; 

これはautoreleaseのオブジェクト..です

あなたは

someSprite = [CCSprite spriteWithFile:@"SomeFile.png"]; 

を行うときに、自動解放オブジェクトにsomeSpriteを指す..

このライン合成の全体のポイントを混乱させる(保持する)。このラインを

[self setsomeSprite] =[CCSprite spriteWithFile:@"SomeFile.png"]; 
に変更する

あなたはむしろself.someString` `よりsomeString``に割り当てについて正しかった今、あなただけ...それは...のdeallocでsomeSprite releaseを持っていた方法を継続し、すべてが

+0

基本的にプロパティとして変数を作成したときはいつでも...あなたは[self setVariable] =またはself.variable =を行う必要があります。決して変数= ...を決して行うことは決してありません。 – Shubhank

関連する問題