Проблема с UITableView в качестве подпредставления в NIB - PullRequest
3 голосов
/ 21 ноября 2010

Резюме: я пытаюсь использовать UITableView как подпредставление "основного" вида моего окна; оно появляется, но когда я прокручиваю окно, я получаю следующее сообщение об ошибке:

2010-11-20 17:17:51.958 xwtf[6997:207] -[NSCFString tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance 0x5f46550

У меня есть подкласс ViewController с соответствующим файлом NIB, который загружен моим делегатом приложения. Это ваш типичный шаблон нового проекта. В этот файл NIB я добавляю UITableView как подпредставление представления. В Интерфейсном Разработчике я изменяю его размер так, чтобы он занимал все окно (т.е. он полностью перекрывает родительский вид).

Теперь мне нужно указать источник данных и делегировать. Я создаю класс с именем DumbTableHelper примерно так:

@interface DumbTableHelper : NSObject<UITableViewDelegate, UITableViewDataSource> {
}

Итак, это не подкласс UIViewController, но я пытаюсь сохранить это простым - все, что мне нужно, - это делегат и источник данных, к которому он может обращаться, верно? Помимо dealloc, мои методы в его файле .m:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  return 1;
}

- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section {
  return 10;
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  static NSString *CellIdentifier = @"DumbTableCell";
  UITableViewCell *cell = [tableView
                           dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                     reuseIdentifier:CellIdentifier]
            autorelease];
  }
  return cell;
}

Как видите, я даже не настраиваю ни одну ячейку; Я просто указываю 10 строк, что достаточно для принудительной прокрутки. В любом случае, в Интерфейсном Разработчике я перетаскиваю объект из библиотеки в мою NIB. Затем я изменяю имя его класса на DumbTableHelper и указываю его в качестве источника данных и делегата уже UITableView. Когда я запускаю его, появляется таблица. Когда я пытаюсь прокрутить таблицу вниз, я получаю:

010-11-20 18:19:54.673 xwtf[6997:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance 0x5f46550'
*** Call stack at first throw:
(
0   CoreFoundation                      0x0259eb99 __exceptionPreprocess + 185
1   libobjc.A.dylib                     0x0239340e objc_exception_throw + 47
2   CoreFoundation                      0x025a06ab -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3   CoreFoundation                      0x025102b6 ___forwarding___ + 966
4   CoreFoundation                      0x0250fe72 _CF_forwarding_prep_0 + 50
5   UIKit                               0x00321d6f -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 619
6   UIKit                               0x00317e02 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
7   UIKit                               0x0032c69f -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1348
8   UIKit                               0x003247ec -[UITableView layoutSubviews] + 242
9   QuartzCore                          0x0455c481 -[CALayer layoutSublayers] + 177
10  QuartzCore                          0x0455c1b1 CALayerLayoutIfNeeded + 220
11  QuartzCore                          0x045552e0 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 302
12  QuartzCore                          0x04555040 _ZN2CA11Transaction6commitEv + 292
13  QuartzCore                          0x04585ebb _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
14  CoreFoundation                      0x0257ff4b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
15  CoreFoundation                      0x02514b27 __CFRunLoopDoObservers + 295
16  CoreFoundation                      0x024ddce7 __CFRunLoopRun + 1575
17  CoreFoundation                      0x024dd350 CFRunLoopRunSpecific + 208
18  CoreFoundation                      0x024dd271 CFRunLoopRunInMode + 97
19  GraphicsServices                    0x02d5d00c GSEventRunModal + 217
20  GraphicsServices                    0x02d5d0d1 GSEventRun + 115
21  UIKit                               0x002beaf2 UIApplicationMain + 1160
22  xwtf                                0x00001af4 main + 102
23  xwtf                                0x00001a85 start + 53
)

Значит, он звонит tableView:cellForRowAtIndexPath: на .. строку? У кого-нибудь есть идеи?

Извините, если это окажется глупым вопросом - до сих пор все мои представления таблиц были созданы программно UITableViewController экземплярами, но теперь мне нужно добавить UITableView в качестве подпредставления, что не Не занимай весь экран. Я прочитал руководство Apple по просмотрам таблиц и разработке iPhone, чтобы убедиться, что ничего не пропустил, но безрезультатно.

Спасибо!

Ответы [ 2 ]

4 голосов
/ 22 ноября 2010

Хорошо, я понял, почему: у моего подкласса ViewController, который также является владельцем файла в моем NIB-файле, нет объявленного выхода на DumbTableHelper. В Руководстве по программированию ресурсов для файлов Nib на http://developer.apple.com/library/mac/documentation/cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html написано:

Объекты в файле пера создаются с счетом сохранения 1 и затем автоматически высвобождаются ... Если вы определяете выходы для объектов файла пера, вы всегда должны определять метод установки (или объявленное свойство) для доступа к этому выходу. Методы установки для торговых точек должны сохранять свои значения, а методы установки для торговых точек, содержащих объекты верхнего уровня, должны сохранять свои значения, чтобы предотвратить их освобождение.

Когда таблица отображается в первый раз, DumbTableHelper по-прежнему имеет retainCount, равный 1, и еще не была автоматически выпущена, поэтому ее можно использовать для заполнения строк, которые первоначально отображаются. Однако, когда я прокручиваю, он больше не существует в памяти. Из трассировки стека можно предположить, что строка была выделена в адресе памяти, где был DumbTableHelper, и поэтому она ошибочно получает сообщение tableView:cellForRowAtIndexPath:.

Опять же, простое подключение выхода владельца файла к экземпляру DumbTableHelper в файле Interface Builder решает проблему.

0 голосов
/ 22 ноября 2010

Я предлагаю удалить ваши соединения в Интерфейсном Разработчике и попытаться восстановить.Конечно, кажется, что выход источника данных был подключен к NSString в наконечнике.Вы также можете просто попытаться установить соединение в коде, используя свойства делегата и источника данных UITableView.

...