开发者

EXC_BAD_ACCESS when debugging

I'm getting this error when trying to see the contents of a 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;

In viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];

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

... Populate the people array with Person objects.

}

When I'm at the point where I'm modifying the contents of a cell in the tableview, I'm unable to access the people array in gdb when typing 'po self.peopl开发者_开发百科e':

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

Any ideas why I can't access it?


The line

people = [NSMutableArray array];

returns an autoreleased array that will be released on the next iteration of the current run loop. You should retain that:

people = [[NSMutableArray array] retain];

and of course release it in your dealloc method.

However: Apple engineers have often mentioned in conferences to avoid autoreleased instances like this whenever possible in the iPhone, for performance reasons. Try using alloc/init instead:

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

with the corresponding release in the dealloc method. In this case you don't even need to retain (init returns an instance with a retain count of 1, which is what you need).

And justin's comment is correct: you should do this instead:

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

and this should work.


is indexPath.row > [people count]?

Also, why are you doing this:

Person *person = [[Person alloc] init]

You're allocating memory, and then pointing to completely different memory.


You can avoid having to fuss with retaining properties by using the self notation to call the accessor and setter methods created by the @synthesize directive.

When you set the people property directly in viewDidLoad it sets the property but does nothing for memory management. However, if you set it with self.people you actually call the synthesized setter method that because of the retain setting of the @property directive will automatically retain the assigned array.

As an aside, I would recommend always using -[NSMutableArray initWithCapacity:] instead of a bare init. It is the actual initializer for the class. You can call it with just '1' if you don't know how big it will be. In the past, I have seen odd problem arise from just using bare init.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜