0

我的对象有一个私人的NSMutableArray项目。我使用下面的代码的大小顺序在项目的对象进行排序:排序NSMutableArray内存泄漏

-(void)sortItems{ 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"size" ascending:YES];  
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; 
NSArray *sortedArray = [items sortedArrayUsingDescriptors:sortDescriptors]; 
NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray]; 
[self setItems:newArray]; 
[sortDescriptor release]; 

}

显然,这是这里的内存泄漏,因为每次我打电话sortItems时间,我allocing新的内存和分配项目指向它。我试着释放旧的内存如下:

NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray]; 
NSMutableArray* oldArray = [self items]; 
[self setItems:newArray]; 
[oldArray release]; 

但是,这给出了一个EXC_BAD_ACCESS错误。我已经阅读了objC中的内存处理,并且我确信我在这里做了一些根本性错误。

任何帮助将不胜感激!

+0

显示你的'setItems'方法的实现/声明。 *应该*保留'newArray',这意味着你需要在调用它之后立即调用[newArray release]。 – trojanfoe 2012-02-21 14:45:19

+0

目前项目属性: @property(nonatomic,assign)NSMutableArray * items;我想我需要阅读何时在属性标志中使用“保留”! – JimmyB 2012-02-21 15:02:47

回答

2

你泄露新的数组,而不是旧的:

NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray]; 
[self setItems:newArray]; 
[sortDescriptor release]; 
[newArray release]; // <-- add this 

的基本规则是,你必须释放你分配什么,你通常不应该关心保持为任何人保留的东西(即[self setItems:]),那些需要保留的东西将自己做。

我还建议让self.items成为一个可变数组,并使用[self.items sortUsingDescriptors:sortDescriptor排序而不创建副本。

+0

太棒了!非常感谢。应该将项目的属性标志设置为保留,而不是分配? – JimmyB 2012-02-21 15:05:33

+0

@JimmyB我以为他们已经是。是的,对于这个用例,他们应该是。如果您的对象是数组的所有者,则它是保留该数组的人。 – hamstergene 2012-02-21 15:12:40

+0

这看起来应该可以工作,但出于某种原因,添加这个[newArray发布]甚至在它碰到这个函数之前崩溃了应用程序......非常奇怪! – JimmyB 2012-02-21 15:13:38

0

有没有理由不能在第一个例子中释放newArray?

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"size" ascending:YES];  
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; 
NSArray *sortedArray = [items sortedArrayUsingDescriptors:sortDescriptors]; 
NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray]; 
[self setItems:newArray]; 
[newArray release]; 
[sortDescriptor release];