模拟低内存警告时NSArray导致内存泄漏

时间:2011-05-27 10:21:14

标签: iphone objective-c ios memory-leaks nsarray

我制作了一个示例项目来重现这个包含两个视图的问题:

root header:

#import <UIKit/UIKit.h>
#import "view2.h"

@interface RootViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>{
    view2 *secondView;
    UITableView *table;
    NSArray *array;
}

@property (nonatomic, retain) view2 *secondView;
@property (nonatomic, retain) IBOutlet UITableView *table;
@property (nonatomic, retain) NSArray *array;
@end

root main:

#import "RootViewController.h"

@implementation RootViewController
@synthesize table, array, secondView;

- (void)viewDidLoad
{
    [super viewDidLoad];    
    if(self.array == nil){
        self.array = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil];
    }
}
- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

}

- (void)viewDidUnload
{
    [super viewDidUnload];
    table = nil;
    array = nil;
    secondView = nil;

}

- (void)dealloc
{
    [table release];
    [array release];
    [secondView release];
    [super dealloc];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [array count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.text = [array objectAtIndex:indexPath.row];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    if (secondView == nil) {
        secondView = [[view2 alloc] init];
    }
    [self.navigationController pushViewController:secondView animated:YES]; 
}
@end

view2 simple包含带有文本“view 2”的标签,用于识别目的。 所有这些代码在根控制器中执行的是创建一个值为1,2,3,4的数组,并将此文本作为行绑定到表中,单击任何行将视图2推送到堆栈上。 如果您使用泄漏工具工具在模拟器中加载应用程序,请单击任何行以显示view2,然后模拟错误警告,显示以下泄漏: image 对于该行:

self.array = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil];

这在我的主应用程序中引起了很多问题,因为我使用数组在整个地方的表格中提供数据。

我已经尝试了各种方法来解决这个问题,例如以不同的方式声明数组无济于事。

非常感谢任何帮助!

感谢

1 个答案:

答案 0 :(得分:5)

viewDidUnload中,您将财产与直接ivar访问混为一谈。

array = nil只需将ivar设置为nil,而无需使用合成的存取方法。您必须使用点表示法:self.array = nil;

这样就使用了访问器setArray:来处理内存管理。

混合ivars和属性是Objective-C初学者的常见问题。通过始终对属性和ivars使用不同的名称,可以轻松避免混淆:

@synthesize array = _array;

您可以在课程@interface中省略ivar声明,或将其命名为@synthesize指令。