2009-08-17 2 views
1

原因 - (無効)setUserFilters {配列は、リーク

//init the user filters array 
    userFilters = [[NSMutableArray alloc] init]; 
    SearchCriteria *tmpSc= [[SearchCriteria alloc] init]; 
    for(int i=0;i<[searchFilters count];i++) 
    { 
    tmpSc=[self.searchFilters objectAtIndex:i]; 
    if(tmpSc.enabled==TRUE) 
     [userFilters addObject:tmpSc]; 
    } 
    } 

searchFiltersをtrueまたはfalseにsettedと私だけなフィルタとテーブルビューを移入するためにuserFiltersを使用することができるフィルタのリストです。 TRUEに設定されています

しかし、行SearchCriteria * tmpSc = [[SearchCriteria alloc] init];私は関数の終わりに私のポインタを緩めるとそれがクラッシュするので、リークを引き起こすと私は解決する方法がわからない

すべてのアイデア?

答えて

5

twolfe18は、searchFiltersが大きくなる可能性がある場合は、コードを>非常に遅くしました。 -objectAtIndex:は大容量アレイでは高速動作ではありませんので、必要以上に行うべきではありません。 (FEはobjectAtIndex:よりも高速ですが、これは問題を誇張していますので、私はそれを打ち破っています; Fast Enumerationの利点に関する他のコメントを参照してください)

コードにはいくつかの問題があります。

  • 「設定」を開始するがアクセサーではないメソッドを作成しないでください。 Objective-CがKey-Value準拠を提供する方法により、これは非常に驚くべきバグにつながります。名前は重要です。 userFiltersという名前のプロパティは、-userFiltersというゲッターと-setUserFilters:というセッターを持つ必要があります。セッターはゲッターが返すのと同じ型を取るべきです。だから、この方法は、この問題を避けるため(そしてそれが何をするかをより正確に示すために)、-updateUserFiltersといいます。

  • 常にアクセサを使用してください。彼らはあなたにあらゆる種類のメモリ管理の問題を救います。 -setUserFiltersが2回呼び出されると、現在のコードが配列全体をリークします。

  • 両方のコメントは、ここで一時的に割り当てる必要はありません。実際には、Fast Enumerationを使用することをお勧めします。Fast Enumerationは非常に速く、非常にメモリ効率が良い(コード作成が簡単です)。

    @interface MyObject() 
    @property (nonatomic, readwrite, retain) NSMutableArray *userFilters; 
    @property (nonatomic, readwrite, retain) NSMutableArray *searchFilters; 
    @end 
    
    @implementation MyObject 
    @synthesize userFilters; 
    @synthesize searchFilters; 
    
    - (void)dealloc 
    { 
        [searchFilters release]; 
        serachFilters = nil; 
        [userFilters release]; 
        userFilters = nil; 
        [super dealloc]; 
    } 
    
    
    - (void)updateUserFilters 
    { 
        //init the user filters array 
        // The accessor will retain for us and will release the old value if 
        // we're called a second time 
        self.userFilters = [NSMutableArray array]; 
    
        // This is Fast Enumeration 
        for (SearchCriteria *sc in self.searchFilters) 
        { 
         if(sc.enabled) 
         { 
          [self.userFilters addObject:sc]; 
         } 
        } 
    } 
    
    :すべて一緒にそれを引っ張る

、ここであなたは(他の多くの優れたソリューションがありますが、それを行うには、少なくとも一つの方法を、しかし、この1つは理解することは非常に簡単です)やって欲しいものです

+0

'objectAtIndex'は一定時間(配列です!)で動作しますが、大きな配列ではそれほど遅くならない、つまり愚かです。 あなたがそれをテストしたことを正直に伝えたいならば、 'objectAtIndex'はあなたが推奨するものより2%以上遅いです。そうすれば、何か他のものにあなたの時間を費やす方が良いでしょう。 – twolfe18

+1

私は、ループで行われている作業の複雑さに応じて、ループの2%〜35%の改善を測定しました(明らかに、ループの作業が少なくなるほど改善されています)。より少ないタイピングが必要であるという事実は、通常、十分なポイントを売ることです。たとえ突然変異が別のスレッドで起こったとしても、誤って間違った動作ではなくループ中に誤って配列を突然変異させると、例外が発生します。知覚されるパフォーマンスが劇的に向上することはよくありません。 –

+2

NSArrayは配列のような操作をサポートするオブジェクトへのインターフェイスを提供するという意味で「配列」です。これは、C配列のように実装されていることは保証されていません。また、オブジェクトへのアクセスの高速性に関するパフォーマンスの保証はありません。 – peterb

0

まず、書くことができる最悪のn00bコードはif(condition==true) do_something()です。ちょうどif(condition) do_something()と書いてください。

-(void)setUserFilters{ 

//init the user filters array 
userFilters = [[NSMutableArray alloc] init]; 
for(int i=0;i<[searchFilters count];i++) 
{ 
    if([self.searchFilters objectAtIndex:i].enabled) 
      [userFilters addObject:[self.searchFilters objectAtIndex:i]]; 
} 
} 
+0

また、Objective-Cではキーワードは 'true&false'ではなく' YES&NO'です。時には真実は働きますが、それに頼ることはありません。 – jbrennan

+0

正解、Objective-CはYESとNOを使用しますが、TRUE、FALSE、TRUE、FALSEはYESとNOに解決するためにすべて定義されています。私は本当か偽がうまくいかないケースは見ていない。良いスタイルは、あなたはYESとNOを使うべきだと言います。 – twolfe18

+2

YESは、符号付きcharへの1キャストとして定義されます。 trueはCのシンボル "1"に置き換えられます(したがって、その型とサイズは未定義です)。 C++ではtrueはbool型です。はい、条件付きでも同様に解決されます。それらは同じサイズではなく、同じものをエンコードすることはできません。それらを混ぜないでください。 Objective-Cの真理値はYESで、その型はBOOLです。 –

2

あなたが最初にあなたの前にSearchCriteriaオブジェクトを作成しているようだ:

二つ目は、あなたが次の操作を行うだけでできる、(それのためのallocメモリを気にしない)まったくtempScを持っている理由はありませんそれを使用するか、self.searchFiltersの別のオブジェクトに変数を再割り当てします。したがって、最初のオブジェクトを作成する必要はなく、なぜそれが漏れていて、解放されていないのですか。

試してみてください。役立ちます

SearchCriteria *tmpSc = nil; 

希望。

+0

= nil、あなたが意味すると思う - nullはJava-ismで、NULLは他のポインタ型のvoid *です。彼らは同じタイプにコンパイルするので、あなたはどちらかを使用して終了することができます... – AlBlue

+0

はいあなたのかなり正しい私はゼロを意味した。ありがとうございました。 –