0

UITableView があり、テーブルスワイプメソッドからの削除を実装しました。
何らかの理由で、配列の割り当てが原因でアプリがクラッシュしています。
理由を知りたいです。

2 つのプロパティ:

@property (nonatomic,retain) NSMutableArray *mruItems;
@property (nonatomic,retain) NSArray *mruSearchItems;
 . 
 .
 .
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle != UITableViewCellEditingStyleDelete)
        return;

    NSString *searchString = [self.mruSearchItems objectAtIndex:indexPath.row];
    [self.mruItems removeObject:searchString];

    [self.mruSearchItems release];

    // This line crashes:
    self.mruSearchItems = [[NSArray alloc] initWithArray:self.mruItems];

    [self.searchTableView reloadData];
   }

mruItems のオブジェクトが削除された後、mruSearchItems の初期化を助けることができないかのようです...

ありがとう!

編集:

EXC_BAD_ACCESS

@synthesize mruItems,mruSearchItems; <--デバッガーはここを指す

4

3 に答える 3

3

ダブルリリースはクラッシュの原因となります。

[self.mruSearchItems release];

これにより、参照カウントが-1になります

self.mruSearchItems = [[NSArray alloc] initWithArray:self.mruItems];

これにより、参照カウントが-1になります

mruSearchItems にはプロパティ属性に「retain」があるため、それに割り当てると、別の refcount -1 が発生します。

したがって、リリース行を削除するか、リリース後、割り当て前に nil に設定してください。


編集:この行

self.mruSearchItems = [[NSArray alloc] initWithArray:self.mruItems];

メモリ リークが発生する場合は、次のように修正します。

self.mruSearchItems = [[[NSArray alloc] initWithArray:self.mruItems] autorelease];

また:

NSArray *tmpArray = [[NSArray alloc] initWithArray:self.mruItems];
self.mruSearchItems = tmpArray;
[tmpArray release];

再編集

プロパティの「保持」は実際に何をしますか?

割り当てるときは、mruSearchItems を例に取ります。

- (void)setMruSearchItems:(NSArray *)newArray
{
    [newArray retain];
    [mruSearchItems release]; // this lines causes a second release to the old value
    mruSearchItems = newArray;
}
于 2012-07-12T01:40:59.567 に答える
1

オブジェクトを解放して再割り当てする必要があるのはなぜですか? を作成mruSearchItemsすると、次のNSMutableArrayように呼び出すことができます。

[mruSearchItems removeAllObjects];
[mruSearchItems addObjectsFromArray:self.mruItems];

お役に立てれば

于 2012-07-12T04:32:04.670 に答える
0

配列のリリースで問題が発生していると思います。これが役立つことを願っています

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

NSString *searchString = [self.mruSearchItems objectAtIndex:indexPath.row];
 [self.mruSearchItems removeObjectAtIndex:searchString]
[self.searchTableView reloadData];

}

于 2012-07-12T04:49:55.490 に答える