0

次のプロパティを持つ NSMutableArray があります。

@property (nonatomic, strong) NSMutableArray *alarmTableArray;

alarmTableArray = [[NSMutableArray alloc]init];
FMDBDatabaseAccess *db = [[FMDBDatabaseAccess alloc] init];
alarmTableArray = [db getAlarm];

この配列を解放しようとしましたが、EXC_BAD_ACCESS になります。
私はこれについて本当に心配しています。

このアレイを解放するには?

4

3 に答える 3

2

ARC用語である「強い」という記述子を使用しています。これは保持する必要があり、プロパティを nil に設定すると、自動的に解放されます。ViewWillDisappear はビューコントローラーが可視性を離れていることを意味するだけであり、破棄されていることを意味しないため、viewDidUnload で nil に設定する必要があります。

于 2012-08-15T19:57:25.683 に答える
1

更新された回答

私はあなたが何をしようとしているのか知っていると思います。SQL から行の配列を取得し、それを配列の 1 つに格納します。

SQL からデータ行を取得してクラス インスタンス変数配列に格納する手法の 1 つは、一時配列を返すのではなく、クラス インスタンス変数配列を参照としてメソッドに渡し、配列を直接変更することです。

したがって、この擬似コードの代わりに

-(NSMutableArray *)doSomething
{
   NSMutableArray *tempArray;

   while (DB select statement has found rows)
   {
       CockTail *objCT = [[CockTail alloc] init];

       objCT.name = @"...";
       objCT.price = @"...";

       [tempArray addObject:objCT];

       [objCT release];
   }

   return [tempArray autorelease];
}

// class instance variable array
instanceVarArray = [[NSMutableArray alloc] init];
instanceVarArray = [self doSomething]; // here is where you confusion arise

次の方法で実行できます。

-(void)doSomething:(NSMutableArray *)paramArray
{
    // remove previously fetched data
    [paramArray removeAllObjects];

    SQL select statement

    while(has rows)
    {
        CockTail *objCT = [[CockTail alloc] init];

        objCT.name = @"...";
        objCT.price = @"...";

        // NOTE: we are directly modifying our class instance variable array
        // here since it was passed by reference :D
        // and so there is no need to worry about releasing the array
        [paramArray addObject:objCT];

        [objCT release];
    }
}

// Now all you do is pass in your class instance variable array
instanceVarArray = [[NSMutableArray alloc] init];
[self doSomething:instanceVarArray];

元の回答

うーん、多分私は間違っているかもしれませんが、FMDBDatabaseAccess から配列に何かを割り当てるときに、ここの最初の行にある「alloc init」を本質的に捨てていませんか?

// LINE 1: this instance of NSMutableArray here is allocated
alarmTableArray = [[NSMutableArray alloc]init];

// LINE 2
FMDBDatabaseAccess *db = [[FMDBDatabaseAccess alloc] init];

// LINE 3:this line here essential breaks the pointer link point to the NSMutableArray instance on line 1 
alarmTableArray = [db getAlarm];

今あなたがしない限り

// LINE 4
[alarmTableArray retain];

そうしないと、alarmTableArray が割り当てられませんでした (ポインター リンクを上書きしたため)。その結果、プロファイラーが言ったように、メモリ リークが発生しました。

今すぐリリースすると、EXEC_BAD_ACCESSが得られます

あなたがやりたいと思うことはこれです:

alarmTableArray = [[NSMutableArray alloc]init];
FMDBDatabaseAccess *db = [[FMDBDatabaseAccess alloc] init];

// this now uses the setter method (mutator method generated by @property) to do the copy
self.alarmTableArray = [db getAlarm];
于 2012-08-16T08:37:24.593 に答える
0

while ループを見て、ローカル スコープ変数を解放する理由を尋ねなければなりません。

 CockTail *cocktailValues = [[CockTail alloc] init];
 ...

 [cocktails addObject:cocktailValues];
 [cocktailValues release];

上記のコードの各行の内訳:

  1. CockTail オブジェクトを割り当てて初期化すると、解放/保持カウントは 0 になります。
  2. オブジェクトを NSMutableArray に追加すると、解放/保持カウントが 1 に増えます。
  3. 配列に追加した後に CockTail オブジェクトを解放すると、解放/保持カウントが 0 に戻ります。

したがって、後で NSMutableArray を解放するか、その中のオブジェクトにアクセスしようとすると、オブジェクトは既になくなっています。

一番のルールを覚えておいてください。保持しているものだけをリリースしてください。

于 2012-08-15T21:26:46.870 に答える