Я определяю свой массив в своем AppDelegate.h так:
NSMutableArray *myWishesArray;
.
.
@property (nonatomic, retain) NSMutableArray *myWishesArray;
In AppDelegate.m, i allocate its object like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
myWishesArray = [[NSMutableArray alloc] init];
.
.
return YES;
}
Предположим, у меня есть функция "Добавить данные в массив", например:
-(void)addDataToArray
{
NSMutableArray *tempArray = //Gets data from a web service
if ([tempArray count] > 0) {
[objAppDelegate.myWishesArray addObjectsFromArray:tempArray];
[self.myWishesTableView reloadData];
}
}
В viewDidLoadMyViewController.m, я загружаю первый набор из 8 записей в мой массив:
- (void)viewDidLoad {
[self addDataToArray]; //fetches page number 1 of the data to be fetched
}
В scrollViewDidEndDragging из MyViewController.m я добавляю следующий набор из 8 записей и использую тот же вышеупомянутый код, чтобы добавить егов objAppDelegate.myWishesArray:
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
currentPageNumber++;
[self addDataToArray]; //fetches data for next page number
}
-(void)viewWillAppear:(BOOL)animated
{
[self.myWishesTableView reloadData];
}
Это мой метод cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyObject *myArrayObject = [objAppDelegate.myWishesArray objectAtIndex:indexPath.row];
}
Каждый раз, когда я пытаюсь щелкнуть строку таблицы, которая была видна в моем представлении таблицы, нобыло только в конце загрузки, мое приложение зависало со следующим исключением.Это может быть начальная загрузка или загрузка большего количества строк в результате прокрутки вниз представления таблицы.Пожалуйста, имейте в виду, что когда я даю табличному виду достаточно времени для установления, и движение останавливается и данные полностью загружаются, я не сталкиваюсь ни с каким исключением при нажатии на загруженные строки.
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 0 beyond bounds for empty array'
*** Call stack at first throw:
(
0 CoreFoundation 0x013a8be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x014fd5c2 objc_exception_throw + 47
2 CoreFoundation 0x0139e80c -[__NSArrayI objectAtIndex:] + 236
3 WishHaHa 0x00004e1a -[AsyncImageView image] + 66
4 UIKit 0x0044e56b -[UIImageView setBackgroundColor:] + 101
5 UIKit 0x00549448 -[UITableViewCell _setOpaque:forSubview:] + 953
6 UIKit 0x0054951c -[UITableViewCell _setOpaque:forSubview:] + 1165
7 UIKit 0x0054951c -[UITableViewCell _setOpaque:forSubview:] + 1165
8 UIKit 0x0054472d -[UITableViewCell(UITableViewCellStatic) _updateAndCacheBackgroundColorForHighlightIgnoringSelection:] + 117
9 UIKit 0x0054c12a -[UITableViewCell showSelectedBackgroundView:animated:] + 1435
10 UIKit 0x00548ce3 -[UITableViewCell setHighlighted:animated:] + 231
11 UIKit 0x003fbd3b -[UITableView highlightRowAtIndexPath:animated:scrollPosition:] + 756
12 UIKit 0x003f78d8 -[UITableView touchesBegan:withEvent:] + 1349
13 UIKit 0x004512b8 forwardMethod2 + 92
14 UIKit 0x0054cc15 -[UITableViewCell touchesBegan:withEvent:] + 319
15 UIKit 0x004512b8 forwardMethod2 + 92
16 UIKit 0x00610987 _UIGestureRecognizerSortAndSendDelayedTouches + 3609
17 UIKit 0x006110fc _UIGestureRecognizerUpdateObserver + 927
18 CoreFoundation 0x01389fbb __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
19 CoreFoundation 0x0131f0e7 __CFRunLoopDoObservers + 295
20 CoreFoundation 0x012e7bd7 __CFRunLoopRun + 1575
21 CoreFoundation 0x012e7240 CFRunLoopRunSpecific + 208
22 CoreFoundation 0x012e7161 CFRunLoopRunInMode + 97
23 GraphicsServices 0x01a9d268 GSEventRunModal + 217
24 GraphicsServices 0x01a9d32d GSEventRun + 115
25 UIKit 0x0039442e UIApplicationMain + 1160
26 WishHaHa 0x00002a5c main + 102
27 WishHaHa 0x000029ed start + 53
)
terminate called after throwing an instance of 'NSException'
Я сделалМного исследований моей проблемы и обнаружил, что возможные причины NSRangeException могут быть:
- numberOfRowsInSection: (NSInteger) раздел;метод источника данных UITableView доставляет неправильные значения.
- retain должен вызываться для массива.
- Всякий раз, когда вы изменяете базовые данные для табличного представления, вам необходимо обновить изменения, вызвав их- [UITableView reloadData];или методы beginUpdates и endUpdates с последующим добавлением или удалением правильных путей индекса.
Я не думаю, что мой код имеет первую проблему.Если есть вторая проблема, то где я должен сделать вызов, чтобы сохранить myWishesArray?Если с моим кодом возникла третья проблема, то как мне перейти к изменению кода?
Пожалуйста, дайте мне знать, где я делаю что-то не так.Я застрял в этом вопросе очень долго.
Спасибо
Редактировать:
После тщательного изучения кода я нашел точку, котораявызывает эту ошибку.Я асинхронно загружаю изображения в ячейки моего табличного представления, используя класс asyncimageview.Позвольте мне вставить здесь некоторый код:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"CustomWishCell";
CustomWishCell *cell = (CustomWishCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomWishCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomWishCell *) currentObject;
break;
}
}
}
else
{
AsyncImageView* oldImage = (AsyncImageView*)[cell.contentView viewWithTag:999];
[oldImage removeFromSuperview];
}
if (indexPath.row<[objAppDelegate.myWishesArray count]) {
Wish *objWish = [objAppDelegate.myWishesArray objectAtIndex:indexPath.row];
NSString *test = objWish.facebookUserId;
[self.myEngine loadAsynchronousPhotoAvatarInView:objWish.facebookUserId imageView:cell.contentView];
cell.wishLabel.attributedText = [self.myEngine makeWisherNameAndContents:objWish.firstName lastName:objWish.lastName wishContents:objWish.contents];
}
return cell;
}
Теперь myEngine содержит определение:
-(void)loadAsynchronousImageURLInView:(NSString*)imageUrl imageView:(UIView*)targetView
{
CGRect frame;
frame.size.width=45;
frame.size.height=45;
frame.origin.x=0;
frame.origin.y=0;
if (imageUrl != (id)[NSNull null] )
{
AsyncImageView* asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
asyncImage.tag = 999;
NSURL *url = [NSURL URLWithString:imageUrl];
[asyncImage loadImageFromURL:url];
[targetView addSubview:asyncImage];
}
}
А класс AsyncImageView загружает изображение с помощью класса NSURLConnection.Обратите внимание, что приложение работает нормально, когда я комментирую эту строку, определенную в методе cellForRowAtIndexPath:
[self.myEngine loadAsynchronousPhotoAvatarInView:objWish.facebookUserId imageView:cell.contentView];
Не происходит сбой при нажатии на любую строку, которая загружалась.Пожалуйста, дайте мне знать, как я должен изменить свою логику.Я не могу загружать изображения синхронно или показывать какие-либо индикаторы во время загрузки изображений.