调试时EXC_BAD_ACCESS

时间:2010-01-05 16:42:04

标签: iphone objective-c

我在尝试查看NSMutableArray的内容时遇到此错误:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000021
0x94d5a688 in objc_msgSend ()

ViewController.h:

@interface PeopleViewController : UITableViewController {
    NSMutableArray *people;
}

@property (nonatomic, retain) NSMutableArray *people;

ViewController.m:

@implementation PeopleViewController

@synthesize people;

在viewDidLoad中:

- (void)viewDidLoad {
    [super viewDidLoad];

    // initialize our people array with an autoreleased object
    people = [NSMutableArray array];

... Populate the people array with Person objects.

}

当我正在修改tableview中某个单元格的内容时,我在输入'po self.people'时无法访问gdb中的people数组:

Person *person = [[Person alloc] init];
person = [self.people objectAtIndex: indexPath.row]; // <--- 'po self.people' called  
cell.textLabel.text = person.personName;

为什么我无法访问它的任何想法?

3 个答案:

答案 0 :(得分:7)

该行

people = [NSMutableArray array];

返回一个自动释放的数组,该数组将在当前运行循环的下一次迭代中释放。你应该保留:

people = [[NSMutableArray array] retain];

当然可以在你的dealloc方法中发布它。

但是:出于性能原因,苹果工程师经常在会议中提到尽可能避免像iPhone这样的自动释放实例。请尝试使用alloc / init:

people = [[NSMutableArray alloc] initWithCapacity:1];

在dealloc方法中使用相应的版本。在这种情况下,您甚至不需要保留(init返回一个保留计数为1的实例,这是您需要的。)

贾斯汀的评论是正确的:你应该这样做:

Person *person = [people objectAtIndex:indexPath.row];
cell.textLabel.text = person.personName;

这应该有用。

答案 1 :(得分:4)

是indexPath.row&gt; [人数]?

另外,你为什么要这样做:

Person * person = [[Person alloc] init]

你正在分配内存,然后指向完全不同的内存。

答案 2 :(得分:1)

使用self表示法调用@synthesize指令创建的访问器和setter方法,可以避免不得不保留属性。

直接在people中设置viewDidLoad属性时,它会设置属性,但不会对内存管理执行任何操作。但是,如果使用self.people进行设置,则实际调用合成的setter方法,因为retain指令的@property设置将自动保留指定的数组。

顺便说一句,我建议始终使用-[NSMutableArray initWithCapacity:]而不是裸init。它是该类的实际初始值设定项。如果你不知道它有多大,你可以用'1'来调用它。在过去,我发现只使用裸init会产生奇怪的问题。