EXC_BAD_ACCESS в UITableViewController - PullRequest
       13

EXC_BAD_ACCESS в UITableViewController

0 голосов
/ 03 апреля 2009

Я пытаюсь использовать UITableViewController (делегат и источник данных для представления) для отображения простой таблицы, прочитанной из Plist. Plist содержит NSDictionary, который сам содержит несколько объектов NSDictionary, которые представляют объекты, используемые в моем приложении.

Остальная часть кода выглядит примерно так (упрощенно):

- (void)viewDidLoad {
    [super viewDidLoad];
    [self loadObjectsFromPlist];
}

- (void)loadObjectsFromPlist {
    NSString *objectPlistFile = [[NSBundle mainBundle] pathForResource:@"Objects" ofType:@"plist"];
    NSDictionary *objectsDictionary = [NSDictionary dictionaryWithContentsOfFile:objectsPlistFile];

    objects = [[NSMutableArray alloc] init];
    NSEnumerator *objectEnumerator = [objectsDictionary objectEnumerator];
    NSDictionary *objectData;
    while(objectData = [objectEnumerator nextObject]) {
        [objects addObject:[MyObject objectFromDictionary:objectData]];
    }
}

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

Поскольку я не использую какие-либо разделы, я возвращаю 1 в numberOfSectionsInTableView контроллера.

Метод objectFromDictionary "MyObject" назначает данные, считанные из NSDictionary, новому объекту. Я тоже пытался сохранить, копировать и т. Д., Но это ничего не изменило.

Я получаю EXC_BAD_ACCESS в tableView:numberOfRowsInSection при звонке [objects count]. Я попытался использовать инструмент выделения объектов, но не нашел проблемы. Мой Plist в настоящее время содержит только данные для одного объекта. Отладчик отображает «1 объект» красным цветом для атрибута objects, поэтому я думаю, что это связано с проблемой.

Ответы [ 8 ]

2 голосов
/ 08 апреля 2009

Чтобы убедиться, что данные загружены в нужное время, попробуйте ленивая инициализация:

- (NSArray *)objectsFromPlist {
    if (!objects) {
       ... // initialize once here
    }
    return objects;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [[self objectsFromPlist] count];
}
1 голос
/ 13 апреля 2009

Я предполагаю, что вам, возможно, придется опубликовать весь (соответствующий) код, а не урезанную версию. Не зная, что еще вы можете делать, как в коде, так и в списке, будет трудно это зафиксировать ... мы все здесь просто стреляем вслепую (по общему признанию, это не необычное явление для SO; -)

1 голос
/ 10 апреля 2009

Что такое objects? Можете ли вы показать свой заголовочный файл? Это может дать мне лучшее понимание. Кроме того, вы пытались поставить [super viewDidLoad] после вашего [self loadObjectsFromPlist]? Похоже на проблему времени или objects случайно выпускается одним из ваших методов.

1 голос
/ 07 апреля 2009

Если отладчик показывает, что EXC_BAD_ACCESS происходит в [servers count], правильно ли инициализируется (предполагаемый) ивар servers? Я не нашел ссылки на это в вашем примере кода.

0 голосов
/ 13 апреля 2009

Хорошо, прочитав все ваши ответы и попытавшись найти свою ошибку, я почти полностью переписал свой код. Наконец, я удалил отладочный вывод, добавленный при первой ошибке.

NSLog(@"Object count: %@", [objects count]);

Поскольку NSArray count не возвращает объект, но целое число, это, очевидно, неправильно и должно было быть:

NSLog(@"Object count: %u", [objects count]);

Тем не менее EXC_BAD_ACCESS происходило без этой строки раньше, но, похоже, это замедлило мою отладку. ;) К сожалению, сейчас я не могу воспроизвести реальную проблему.

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

0 голосов
/ 13 апреля 2009

Поместите свой [self loadObjectsFromPlist] перед [super viewDidLoad]. Ваша переменная "objects" никогда не инициализируется, поэтому вы получаете ошибку EXEC_BAD_ACCESS.

0 голосов
/ 11 апреля 2009

Возможно, вы освободили свой UITableViewController, то есть член objects больше не действителен. Убедитесь, что у вас есть ссылка на UITableViewController где-то. Простой способ проверить, так ли это, - добавить вызов [self retain] в ваш метод viewDidLoad (временно!). Если это устранит проблему, вам нужно еще раз проверить, кто владеет контроллером, и убедиться, что он его не выпустил.

РЕДАКТИРОВАТЬ: я думаю, что лучший способ проверить это было бы установить точку останова в вашем методе dealloc.

0 голосов
/ 03 апреля 2009

Похоже, что он вызывает numberOfRowsInSection перед вызовом loadObjectsFromPlist.

Если вы загружаете свой контроллер программно, возможно, попробуйте вызвать loadObjectsFromPlist из initWithFrame: Style: вместо viewDidLoad.

Если бы передо мной был Mac, я бы сделал это сам, но вы можете попробовать установить точки останова и выяснить, в каком порядке эти методы вызываются. Заявления NSLog на всем протяжении также работают.

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