当我在加载表时尝试选择一行时,应用程序崩溃

时间:2011-09-18 15:19:57

标签: iphone uitableview

我在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];
    }

}

在MyViewController.m的viewDidLoad中,我将第一组8条记录加载到我的数组中:

- (void)viewDidLoad {
     [self addDataToArray]; //fetches page number 1 of the data to be fetched
}

在MyViewController.m的scrollViewDidEndDragging中,我添加了下一组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包含definitioin:

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

当我点击正在加载的任何行时,它不会崩溃。请让我知道我应该如何改变我的逻辑。我不允许同步加载图像,或在下载图像时显示任何指示。

2 个答案:

答案 0 :(得分:2)

您正在加载tableview的数组要么没有填满,要么在点击tableView之前被释放。

请添加释放阵列的代码,并确保您正在AppDelegate中合成阵列。

我认为数组存在一些问题,而不是tableView,因为数组变空了。

我希望这会有所帮助。

答案 1 :(得分:0)

听起来好像你的addDataToArray方法在处理点击之前无法检索数据并填充 myWishesArray 数组。 您是否异步从Web服务检索数据? 有没有办法一次检索所有数据而不是按部分检索它?