2009-04-03 2 views
0

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

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

- (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]; 
} 

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

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

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

+0

Следует отметить, что красный цвет для переменной «1 объект» в отладчике просто означает, что его значение изменилось, когда последнее приложение было активным. (Например, что-то было добавлено или удалено.) –

+0

Ах, ладно ... спасибо за это. Так что это не связано с моей проблемой и делает ее еще более загадочной для меня. – Koraktor

+0

Возможно, это просто ошибка транскрипции, но у вас есть [object addObject: [MyObject ..., и это, вероятно, должно быть [objects addObject ... –

ответ

0

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

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

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

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

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

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

+0

Когда вы получите EXC_BAD_ACCESS, перейдите в консоль и введите «bt», чтобы получить трассировку стека. могут быть полезны для вас, а также для людей, которые пытаются вам помочь. – siukurnin

0

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

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

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

+0

Я уже проверил это с помощью отладчика. Как и раньше, отладчик даже отображает данные, загруженные из Plist (хотя и красным). – Koraktor

1

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

+0

О, извините. Я забыл переименовать это в свой текст. Я попытался свести код к минимуму, а также изменил имена переменных, чтобы быть более общим. В моем реальном проекте переменная - это calles 'servers', но она инициализируется как« объекты »в примере кода моего вопроса. – Koraktor

2

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

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

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

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

+0

Нет, я уже пробовал это. Все еще падает. – Koraktor

+0

Попробуйте пропустить загрузку plist и просто поместите объекты = [[NSMutableArray alloc] init]; перед [super viewDidLoad]. Если это решится, то это подтверждает, что существует проблема с синхронизацией. – Jab

+0

Это работает. Но как я могу это разрешить? – Koraktor

0

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

EDIT: Я думаю, лучший способ проверить - установить точку останова в методе dealloc.

+0

Это не сработало. Все еще падает с [self сохранить] в viewDidLoad. – Koraktor

+0

Я добавил точку останова для dealloc своих объектов ... это никогда не называется. – Koraktor

1

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

+0

Это, вероятно, решило бы мою проблему быстрее. Я постараюсь это запомнить. ;) – Koraktor

0

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

+0

Это уже упоминалось Джесси Браун раньше и не сработало. – Koraktor

Смежные вопросы