我刚刚通过仪器泄漏运行我的应用程序,我被告知以下代码会导致泄漏,但我不知道如何。
我使用以下代码在NSMutableArray
中分配了一些viewDidLoad
:
- (void)viewDidLoad {
[super viewDidLoad];
self.currentCars = [[NSMutableArray alloc] init];
self.expiredCars = [[NSMutableArray alloc] init];
}
然后我使用以下内容在我的viewWillAppear
方法中填充这些数组:
[self.currentCars removeAllObjects];
[self.expiredCars removeAllObjects];
for (Car *car in [self.dealership cars]) {
if ([car isCurrent])
[self.currentCars addObject:car];
if ([car isExpired])
[self.expiredCars addObject:car];
}
稍后在代码中我将在这里发布这些数组:
- (void) viewWillDisappear:(BOOL)animated {
if (currentCars != nil) {
[currentCars release], currentCars = nil;
}
if (expiredCars != nil) {
[expiredCars release], expiredCars = nil;
}
[super viewWillDisappear:animated];
}
有什么想法吗?谢谢!
答案 0 :(得分:2)
问题是(可能)您在-viewDidLoad中使用属性访问器进行数组的初始设置。由于良好实现的属性访问器将保留该对象,因此您将从+ alloc获得1个保留,而另一个保留来分配它。要解决此问题,您应该在分配数组后释放它们,或者使用[NSMutableArray array]
来获取用于初始分配的自动释放数组。
答案 1 :(得分:2)
你的泄漏在这里:
self.currentCars = [[NSMutableArray alloc] init];
self.expiredCars = [[NSMutableArray alloc] init];
假设你声明了这样的属性访问:
@property(nonatomic, retain) NSMutableArray *currentCars;
@property(nonatomic, retain) NSMutableArray *expiredCars;
在我看来,找到泄漏的最佳方法(使用仪器除外)是手动跟踪保留计数。
如果您使用例如currentCars
进行此操作,则会轻易发现泄漏。以下是发生的事情:
self.currentCars = [[NSMutableArray alloc] init];
// The 'init' makes the retain count 1.
// 'self.currentCars = ..' translates to the setCurrentCars: method.
// You probably did not implement that method yourself,
// but by synthesizing your property it is automatically implemented like this:
- (void)setCurrentCars:(NSMutableArray *)array {
[array retain]; // Makes the retain count 2
[currentCars release];
currentCars = array;
}
// In your viewWillDisappear: method
[currentCars release], currentCars = nil; // Makes the retain count 1 so the object is leaked.
解决方案很简单。使用此:
NSMutableArray *tempMutableArray = [[NSMutableArray alloc] init];
self.currentCars = tempMutableArray;
[tempMutableArray release];
一个小小的旁注。您不应该在viewWillDisappear:
中发布您的对象。推荐的地方是dealloc
。所以你的代码是:
- (void)dealloc {
[currentCars release], currentCars = nil;
[expiredCars release], expiredCars = nil;
[super dealloc];
}
答案 2 :(得分:0)
除非你在currentCars
,expiredCars
,dealership
或cars
做一些非常奇怪的事情,否则,那里没有泄漏。
仪器指向泄漏位置的指针不一定是物体实际泄漏的地方。如果我猜测,我会说你可能忽略了在你的dealloc方法中释放currentCars
或expiredCars
。