0

我有一个 UITableView 并且我实现了从表格滑动方法中删除。
由于某种原因,数组的分配导致应用程序崩溃。
我想知道为什么。

两个属性:

@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];

这使得 refcount -1

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

这使得 refcount -1

由于 mruSearchItems 在属性属性中具有“保留”,因此您对它的分配将导致另一个 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 回答