2011-01-30 10 views
0

2つのクラスがあるとします。私はClass1.hiphone - @propertyを理解しようとしています

でこれを宣言する最初の1秒クラスの
@interface Class1 : UIViewController { 

    NSString *myString; 
    id myObject; 

} 

で私は

@interface Class2 : UIViewController { 

    NSString *myString; 
    id myObject; 

} 

@property (nonatomic, retain) NSString *myString; 
@property (nonatomic, retain) id myObject; 

とクラス2に、私@synthesizeのmyString、myObjectというようにそれを宣言することを越えて行きます。 m

私のメインプログラムでは、Class1に基づくオブジェクトとClass2に基づくオブジェクトの2つのオブジェクトを作成します。

class2の@propertyにはどのような影響がありますか? Class2の両方の値に割り当てられたすべての値は常に保持されますか?もしそうなら、それらを「解放する」必要がありますか?どうやって?

ありがとうございました。

答えて

3

性質上、完全な説明についてはDeclared Properties section of The Objective-C programming language をお読みください。)

クラス2の場合:

この場合、retainアトリビュートをプロパティに設定すると、実装で保持されるはずです。これは、プロパティを合成するときに自動的に行われます。 myStringとmyObjectという外部から見えないよう これは、あなたが

- (void) dealloc{ 
    [myString release]; 
    [myObject release]; 
    [super dealloc]; 
} 

を持っている必要があり、すべてがclass1で

罰金なければならないことを意味し、プロパティを持っていません。しかし、これはあなたがそれらを解放すべきではありませんことを意味しません。それはあなたがそれらを初期化する方法やメッセージをそれらに保存するかによって決まります。

ところで、assignプロパティを設定しても解放しない場合は、deallocメソッドでnilに設定してください。 copyに設定した場合は、それを解放する必要があります。

EDIT

あなたは言った:*しかし、私はこの*

@property (nonatomic, retain) UIView *myView; 

myView = [[UIView alloc] initWithFrame:myFrame]; 
[self.view addSubview:myView]; 
[myView release]; 

があると?私はすでにmyViewをリリースしています...もう一度リリースする必要がありますか?

まず、あなたがあなたの財産がそのように定義されておりますので、あなたのようにdeallocメソッドを持っている必要があります。だから、

- (void) dealloc{ 
    [myView release]; 
    [super dealloc]; 
} 

、答えはあなたがそれを解放していないが、実際には正しくないはずですNOです。 見てみてください。

myView = [[UIView alloc] initWithFrame:myFrame]; //myView retainCount is 1 
[self.view addSubview:myView]; //retainCount is 2 
[myView release]; //retainCount is 1 again 

後のdeallocメソッドで

- (void) dealloc{ 
    [myView release]; // retainCount becomes 0, is deallocated 
    [super dealloc]; // subviews of self.view are released but myView was already deallocated!, so you have over released myView once ;(
} 

これが正しい方法である:(あなたの特性を使用します。))

UIView *aView = [[UIView alloc] initWithFrame:myFrame]; // init, retainCount is 1 
self.myView = aView; // retainCount becomes 2 
[aView release]; // retainCount becomes 1 again and we are fine. 

[self.view addSubview:self.myView]; //retainCounts becomes 2 again. 

それが2であっても、 self.viewが割り当て解除されると、そのサブビューも解放されるので、問題ありません。 selfが解放されると、self.myView retainCountは再び1になります。

- (void) dealloc{ 
    [myView release]; //retainCounts becomes 1 
    [super dealloc]; // all its subviews of self.view are released hence myView retaincount becomes 1 and is released corretly 
} 

どういう違いがありますか?

self.myViewも他のオブジェクトXによって保持され、前者のアプローチでは、すでにリリースされているため、Xのビューは無効なオブジェクトを指しているとします。あなたは

@property (... retain) NSObject *retainVar; 
@property (... assign) NSObject *assignVar; 
@property (... copy) NSObject *copyVar; 

を持っているとき

、あなたがそれらを@synthesize:

はそれが

bbumの指標としてEDIT2 を役に立てば幸い、これは性質上のミニミニ短いチュートリアルです

は、以下のセッターを有するようなものです。

// retain 
-(void)setRetainVar:(NSObject *)var { 
    if (retainVar != var) { 
     [retainVar release]; 
     retainVar = [var retain]; 
    } 
} 
//assign 
-(void)setAssignVar:(NSObject *)var { 
    assignVar = var; 
} 
//copy 
-(void)setCopyVar:(NSObject *)var { 
    if (copyVar != var) { 
     [copyVar release]; 
     copyVar = [var copy]; 
    } 
} 

(これはあなたが直接割り当てた場合、あなたが確認する必要があり、オブジェクトがビューのメモリ管理の観点から、上記セッターと等価なものであることを意味します)

とあなたのdeallocメソッドのようなものでなければなりません:

例えば、INITの内側にあなたのアイバーズ

を設定

- (void) dealloc{ 
    [retainVar release]; 
    assignVar = nil; 
    [copyVar release]; 
    [super dealloc]; 
} 

- (id) init{ 
    if ((self = [super init])){ 

     //this is ok 
     retainVar = [[NSObject alloc] init];//but is retainVar was not nil we will have a leak ;(

     //This is better 
     NSObject *obj = [NSObject alloc] init]; 
     self.retainVar = obj; 
     [obj release]; 

     //this is BAD 
     assignVar = [[NSObject alloc] init];//because this is like retaining it, later it will leak 

     //below is correct 
     NSObject *obj = [[[NSObject alloc] init] autorelease]; 
     assignVar = obj; 

     //copy is pretty much like retain, 
     //this is ok 
     copyVar = [[NSObject alloc] init]; //but, if copyVar was not nil is a leak! 

     //below is better 
     NSObject *obj = [NSObject alloc] init]: 
     self.retainVar = obj; 
     [obj release]; 

    } 
    return self; 
} 
+1

あなたはその違いを議論する必要があります。インスタンス変数を直接設定し、保持/解放に関してsetter/getterを使用してインスタンス変数を設定します。それがそうであるように、これは誤解を招きます。 – bbum

+0

@bbum - あなたは何を意味するのかを説明する答えを作成できますか? – SpaceDog

+0

@ nacho4d - リリース、右?しかし、私はこの@property(nonatomic、retain)UIView * myViewを持っていると仮定します。私はmyView = [[UIView alloc] initWithFrame:myFrame]を持っています。 [self.view addSubview:myView]; [myViewリリース]; ?私はすでにmyViewをリリースしています...もう一度リリースする必要がありますか? – SpaceDog

関連する問題