2011-02-08 18 views
3

Objective-C 2.0以降で正しい読み取り専用プロパティを作成する方法に関する2つの質問があります。 「『リターンA_』での潜在的な漏れ」:このような警告システムレポート、私はそれをコンパイルし、分析すると正しいreadonlyプロパティを書き込む方法は?

@interface ClassA{ 
@private 
    NSMutableArray *a_; 
} 

// NOTE: no retain 
@property (nonatomic, readonly) NSMutableArray *a; 

@end 


/////////////////////////////////////// 
@implementation ClassA 

@synthesize a = a_; 

- (NSMutableArray *)a{ 
    if(nil == a_){ 
    a_ = [[NSMutableArray alloc] array]; 
    } 
    // Potential leak warning on the following line. 
    return a_; 
} 

- (void)dealloc{ 
    // I released the object here, I think this should be safe. 
    [a_ release]; 
    [super dealloc]; 
@end 

:ここ

はのは、ソリューション1それを呼ぶことにしましょう、私の独創的なアプローチであります。

次にObjective-Cのドキュメントをもう一度読んで、次のような別のアプローチを見つけます。 ソリューション2としましょう。

@interface ClassB{ 
@private 
    NSMutableArray *a_; 
} 

// NOTE: make it retain+readonly 
@property (nonatomic, readonly, retain) NSMutableArray *a; 

@end 


/////////////////////////////////////// 
// Add a private category 
@interface ClassB() 

// reset the property to readwrite 
@property (nonatomic, readwrite, retain) NSMutableArray *a; 

@end 

////// 
@implementation ClassB 

@synthesize a = a_; 

- (id)init{ 
    if(self = [super init]){ 
    // NOTE: set the value as we use property normally. 
    self.a = [NSMutableArray array]; 
    } 
    return self; 
} 

- (void)dealloc{ 
    self.a = nil; 
    [super dealloc]; 
@end 

今、ここに私の質問は以下のとおりです。

  • それは解決策1を使用すると「潜在的な漏れ」を取り除くことは可能ですか?
  • ソリューション2は一般的なソリューションですか?

君たちをありがとう!

- あなたが今、読み取り専用プロパティの値は、前もってなる場合Tonny

+3

'[[NSMutableArrayの -

-deallocで使用するための-deallocおよびおそらくは-initのプロパティを使用しない理由が存在するようにもちろん、私はまだ合成 - この例では、someArray_明示IVARを宣言する。) alloc] array] 'はコンパイラの警告を出さなければなりません。それは間違いなくクラッシュします。 '[[NSMutableArray alloc] init]'が必要です。 –

+0

@ NSMutableArray a_;で '*'を見逃しました – EmptyStack

+0

@Simon、ありがとう、私は手作業でタイプし、コンパイラでコンパイルしませんでした。私はそれを修正しました。 –

答えて

3

、私は答えとして私のコメントを再生しています:

[[NSMutableArray alloc] array]はあなたのコンパイラの警告を与える必要があり、それは間違いなくクラッシュします。あなたは[[NSMutableArray alloc] init]が欲しい。

2

は一般的に、それはinitメソッドでそれを設定するには良いことです。

私は、これは漏れの警告を引き起こすのかはわからないが、私のようなものだろう:

@interface ClassA{ 
@private 
    NSMutableArray a_; 
} 

// NOTE: no retain 
@property (nonatomic, readonly) NSMutableArray a; 

@end 

@implementation ClassB 

@synthesize a = a_; 

- (id)init{ 
    if(self = [super init]){ 
    // NOTE: set the value as we use property normally. 
    a_ = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 

- (NSMutableArray *)a 
{ 
return a_; 
} 

- (void)dealloc{ 
    [a_ release]; 
    [super dealloc]; 
    } 
@end 

EDITED:

固定A_の割り当てを。要求されたよう

+0

criscokidありがとうございました。 私は一般的に、あなたのソリューションは私のものより優れていると思います。はい、私はivarの初期化を '-init'メソッドに入れるべきです。しかし、私はまだ '' _ = [[NSMutableArray alloc] array]; ''の行に潜在的なリーク警告があります。おそらく、これは、このパターンを認識するためにclangが馬鹿だからですか? –

2

正直なところ、私はそれが簡単だけですべてでアイバーズで大騒ぎ "プライベート" 読み書きプロパティを使用していないことを見つける:

MyClass.h

@interface MyClass : NSObject 

@property (nonatomic, copy, readonly) NSArray * someArray; // Public 

@end 

MyClass.m

@interface MyClass()  // Class extension 

@property (nonatomic, copy, readwrite) NSArray * someArray; // "Private" 

@end 

@implementation MyClass 

@synthesize someArray = someArray_; 

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

    if (self != nil) 
    { 
     self.someArray = ...; // Array initialization 
    } 

    return self; 
} 

- (void)dealloc 
{ 
    [someArray_ release]; 

    [super dealloc]; 
} 

@end 

ありませんivarsが必要!現代ランタイムは自動的にそれらを合成します。あなたのプロパティは外部(つまり、他のクラス)から読み込み専用ですが、内部的にはプロパティを読み書き可能と再宣言しているため、合成されたプロパティアクセサの利便性を活用できます。

+0

これは私の**解決策2 ** –

+0

とまったく同じだと思います。それは良いことです。 :) – LucasTizma

関連する問題