EXC_BAD_ACCESS при отладке - PullRequest
       7

EXC_BAD_ACCESS при отладке

1 голос
/ 05 января 2010

При попытке просмотреть содержимое 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.

}

Когда я нахожусь в точке, где я изменяю содержимое ячейки в табличном представлении, я не могу получить доступ к массиву людей в gdb при наборе 'po self.people':

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

Есть идеи, почему я не могу получить к нему доступ?

Ответы [ 3 ]

7 голосов
/ 05 января 2010

Линия

people = [NSMutableArray array];

возвращает автоматически освобожденный массив, который будет освобожден на следующей итерации текущего цикла выполнения. Вы должны сохранить это:

people = [[NSMutableArray array] retain];

и, конечно, отпустите его в методе dealloc.

Тем не менее: Инженеры Apple часто упоминали на конференциях, чтобы избежать подобных случаев, когда это происходит в iPhone, по возможности, из соображений производительности. Попробуйте вместо этого использовать alloc / init:

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

с соответствующим выпуском в методе dealloc. В этом случае вам даже не нужно сохранять (init возвращает экземпляр с счетом сохранения 1, который вам нужен).

И комментарий Джастина верен: вы должны сделать это вместо этого:

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

и это должно сработать.

4 голосов
/ 05 января 2010

это indexPath.row> [количество людей]?

Кроме того, почему вы делаете это:

Person * person = [[Person alloc] init]

Вы выделяете память, а затем указываете на совершенно другую память.

1 голос
/ 05 января 2010

Вы можете избежать суеты с сохранением свойств, используя нотацию self для вызова методов доступа и сеттера, созданных директивой @synthesize.

Когда вы устанавливаете свойство people непосредственно в viewDidLoad, оно устанавливает свойство, но ничего не делает для управления памятью. Однако, если вы установите его с помощью self.people, вы фактически вызовете метод синтезированного сеттера, который из-за установки retain директивы @property автоматически сохранит назначенный массив.

Кроме того, я бы рекомендовал всегда использовать -[NSMutableArray initWithCapacity:] вместо простого init. Это фактический инициализатор для класса. Вы можете назвать это просто «1», если не знаете, насколько он будет большим. В прошлом я видел странную проблему, возникающую при использовании только init.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...