Я получаю EXC_BAD_ACCESS, пытаясь использовать мой подкласс UITableViewController - PullRequest
0 голосов
/ 28 августа 2011

Я пытаюсь включить и изменить заголовки расширяющихся разделов из WWDC 2010 vol128 Мастеринг таблиц.Однако я, должно быть, пропустил шаг или что-то забыл, потому что я получаю ошибку EXC_BAD_ACCESS, когда пытаюсь получить доступ к своему представлению с помощью представления таблицы.

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

Основное различие, которое я вижу, состоит в том, что их версия добавляет подкласс UITableViewController в качестве подпредставления к их appdelegate, т.е.окно.Я хочу добавить свой контроллер в мой scrollview, который находится в viewcontroller.Я уверен, что есть проблема из-за этого?

Оригинал ниже не имеет смысла для меня, потому что он выпускает aTableViewController перед добавлением его в качестве подпредставления, что в моей версии я не могу сделать.Это также делает self.tableViewController = aTableViewController;tableViewController синтезируется наверху так: @synthesize tableViewController=tableViewController_ Я не знаю, откуда он берется, поскольку на него больше нет ссылок нигде в проекте.Опять же, у оригинала был этот код в делегате приложения, так что, возможно, что-то там, что я не знаю, происходит там.

Код Apple (работает):

 TableViewController* aTableViewController = [[TableViewController alloc] initWithStyle:UITableViewStylePlain];
    aTableViewController.plays = self.plays;
    self.tableViewController = aTableViewController;
    [aTableViewController release];

    // Stamdard window display.
    [self.window addSubview:aTableViewController.view];
    [self.window makeKeyAndVisible];

Для целей тестированияЯ создал пустой подкласс testTableViewController, который практически пуст, и попытался добавить его в качестве подпредставления с тем же результатом.Возможно, я неправильно создаю подкласс UITableViewController.Извините, что расплывчато, но я думаю, что это как-то связано с приведенным выше фрагментом информации.

Спасибо

Ответы [ 2 ]

0 голосов
/ 28 августа 2011

Чтобы ответить на это:

Оригинал ниже не имеет смысла для меня, потому что он выпускает aTableViewController перед добавлением его в качестве подпредставления

Вы упомянули:

также делает self.tableViewController = aTableViewController; tableViewController синтезируется вверху так: @synthesize tableViewController = tableViewController_ Я не знаю, откуда это from, поскольку нигде в проекте на него нет ссылок.

Скорее всего, если вы посмотрите в заголовочный файл, вы увидите строку, подобную этой:

@property (nonatomic, retain) tableViewController;

Это «объявленное свойство» в Objective-C. Объявленные свойства обеспечивают супер-удобный способ получения / установки иваров с общими шаблонами (например, сохранение любого назначенного им значения).

Из документации:

Функция объявленных свойств Objective C предоставляет простой способ объявлять и реализовывать методы доступа к объекту.

Обязательно ознакомьтесь с вводной документацией:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html

Свойства оборачивают кучу общих шаблонов проверенными способами.

Например, рассмотрим чью-то (наивную) потенциальную реализацию метода сеттера, который автоматически сохраняет присвоенное ему значение:

- (void) setSomeIvar:(SomeObject *)value
{
     [ivarValue release];
     ivarValue = [value retain];
}

На первый взгляд все в порядке, но рассмотрим следующий фрагмент кода:

1: SomeObject * foo = [SomeObject new];
2: [bar setSomeIvar:foo];
3: [foo release];
...

(позже, возможно, в другом методе, где foo - это то же самое, что и выше):

4: [bar setSomeIvar:foo];

Что бы здесь произошло? Ну, в строке 1, счетчик сохранения равен +1, в строке 2 это +2, строка 3, +1, затем, позже, в строке 4, мы непреднамеренно выпустили объект, прежде чем назначить его на ивар и сохранили его , так что этот код будет ошибка в этой строке.

Более правильный код будет выглядеть примерно так:

- (void) setSomeIvar:(SomeObject *)value
{
     if (ivarValue == value) return;
     [ivarValue release];
     ivarValue = [value retain];
}

Однако шаблоны выходят за рамки даже этого упрощенного примера.

Итак, свойства очень удобны, и заключают в себе всю эту сложность во что-то более надежное и удобочитаемое, чем это возможно.

Они также значительно упрощают проверку того, что вы высвобождаете все, что должны быть в вашем dealloc методе. Просто посмотрите в заголовочном файле все свойства, помеченные (... retain ...), и убедитесь, что они выпущены в dealloc. Кроме того, для UIViewController в частности и их подклассов любые сохраняемые свойства, отмеченные IBOutlet, должны быть установлены на nil в viewDidUnload.

Когда я впервые начал использовать Objective-C, я действительно не использовал свойства - и я страдал за это. Как только я понял их и начал использовать их, они сделали мою жизнь НАМНОГО проще.

0 голосов
/ 28 августа 2011

Контроллеры представлений не сохраняются своими представлениями;среди прочего, это предотвращает циклические ссылки, которые могут затруднить освобождение.:] Вы должны сохранить контроллер вида самостоятельно.Если объявленное вами свойство (self.tableViewController) не сохраняет VC, вы добавите представление в окно, но затем VC (делегат представления для группы событий!) Будет освобожден, а затем выполучить случайный EXC_BAD_ACCESS.

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

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