UITableView вылетает приложение при прокрутке - PullRequest
1 голос
/ 24 ноября 2011

У меня проблемы с поиском решения проблемы, связанной с тем, что мой UITableView не работает, когда приложение прокручивается. Я использую следующий код, взятый из документации Apple:

NSDictionary *categoryArray;
- (void)viewDidLoad
{
    [super viewDidLoad];

    UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"bg_black.png"]];
    self.view.backgroundColor = background;
    [background release];

    MyApp *myapp = [[MyApp alloc ] init];
    categoryArray = [myapp getCategory];

}

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

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Set up the cell...
    NSString *cellValue = [categoryArray objectForKey: [NSString stringWithFormat:@"%d", indexPath.row+1]];
    cell.textLabel.text = cellValue;

    return cell;
}

Где NSDictionary CategoryArray выглядит следующим образом (извлечено из глобального одноэлементного класса):

{
    1 = Bars;
    2 = Nightclubs;
    3 = Societies;
    4 = Colleges;
    5 = University;
}

Я почти уверен, что это какая-то ячейка выделения памяти / переработанная ячейка, но я не могу точно понять, где я ошибаюсь.

Вышла ошибка:

2011-11-23 21:29:01.888 WhatsOniPhone[3759:b303] -[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x4e7a3f0
2011-11-23 21:29:01.892 WhatsOniPhone[3759:b303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x4e7a3f0'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00dde5a9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x00f32313 objc_exception_throw + 44
    2   CoreFoundation                      0x00de00bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x00d4f966 ___forwarding___ + 966
    4   CoreFoundation                      0x00d4f522 _CF_forwarding_prep_0 + 50
    5   WhatsOniPhone                       0x0000340a -[FirstViewController tableView:cellForRowAtIndexPath:] + 314
    6   UIKit                               0x000a5b98 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 634
    7   UIKit                               0x0009b4cc -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
    8   UIKit                               0x000b07f7 -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1348
    9   UIKit                               0x000a890c -[UITableView layoutSubviews] + 242
    10  QuartzCore                          0x016c8a5a -[CALayer layoutSublayers] + 181
    11  QuartzCore                          0x016caddc CALayerLayoutIfNeeded + 220
    12  QuartzCore                          0x016700b4 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
    13  QuartzCore                          0x01671294 _ZN2CA11Transaction6commitEv + 292
    14  QuartzCore                          0x0167146d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
    15  CoreFoundation                      0x00dbf89b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
    16  CoreFoundation                      0x00d546e7 __CFRunLoopDoObservers + 295
    17  CoreFoundation                      0x00d1d1d7 __CFRunLoopRun + 1575
    18  CoreFoundation                      0x00d1c840 CFRunLoopRunSpecific + 208
    19  CoreFoundation                      0x00d1c761 CFRunLoopRunInMode + 97
    20  GraphicsServices                    0x010161c4 GSEventRunModal + 217
    21  GraphicsServices                    0x01016289 GSEventRun + 115
    22  UIKit                               0x0003ec93 UIApplicationMain + 1160
    23  WhatsOniPhone                       0x00002759 main + 121
    24  WhatsOniPhone                       0x000026d5 start + 53
)
terminate called throwing an exceptionsharedlibrary apply-load-rules all

Ответы [ 4 ]

2 голосов
/ 24 ноября 2011

Проблема здесь, помимо прочего, связана с вероятным управлением памятью, как вы и предполагали.Я считаю, что проблема в том, что categoryArray освобождается и заменяется в памяти другим объектом, в случае вашего исключения, NSArray.Решением этой проблемы будет сохранение categoryArray, потому что по какой-то причине сейчас он не сохраняется должным образом вашим контроллером представления.Таким образом, всякий раз, когда вы назначаете categoryArray, делайте categoryArray = [... retain] вместо categoryArray = ....Если вы присваиваете categoryArray как свойство, объявите свойство как @property (nonatomic, retain) NSDictionary * categoryArray.

Если ваш контроллер представления сохраняет владение categoryArray, как и должно быть, необходимо освободить его в методе deallocследующим образом:

- (void)dealloc {
    // if using a property
    self.categoryArray = nil;
    // if not using a property
    [categoryArray release];
    ...
    [super dealloc];
}
1 голос
/ 24 ноября 2011

Похоже, что объект в categoryArray освобождается до того, как вы его используете. Адрес памяти затем повторно используется для другого объекта, который оказывается __NSArrayM.

Вы присваиваете свою переменную в viewDidLoad.

categoryArray = [myapp getCategory];

Невозможно увидеть содержимое getCategory, но я подозреваю, что возвращаемое значение автоматически высвобождается. Следовательно, вам нужно взять на себя ответственность за объект, чтобы он зависал после конца текущего метода.

Вы должны использовать сеттер:

[self setCategoryArray:[myapp getCategory]];

или сохраняя возвращаемое значение:

categoryArray = [[myapp getCategory] retain];

Кроме того, вы должны переименовать этот getCategory метод. По соглашению методы, начинающиеся с get, имеют конкретное значение: они принимают указатель на указатель в качестве аргумента и помещают значение в это место для использования вызывающей стороной. См., Например, -[NSArray getObjects:range:]

1 голос
/ 24 ноября 2011

Эта трассировка стека указывает на то, что вы пытаетесь вызвать метод в классе, у которого нет этого метода.В частности, вы бы позвонили objectForKey в случае NSArray.Вы уверены, что categoryArray является экземпляром NSDictionary, а не NSArray?

1 голос
/ 24 ноября 2011

Из вашей трассировки стека isue исходит из метода objectForKey, вызванного в вашем массиве категорий.

Насколько я понимаю, NSArray не имеет метода objectForKey.Вы можете хотеть NSDictionary.

...