开发者

App crashes when i attempt to select a row while table was loading

I define my array in my AppDelegate.h like this:

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;

}

Suppose i have a function "Add Data to array", like this:

-(void)addDataToArray
{

  NSMutableArray *tempArray =  //Gets data from a web service
    if ([tempArray count] > 0) {
        [objAppDelegate.myWishesArray addObjectsFromArray:tempArray];
        [self.myWishesTableView reloadData];
    }

}

In viewDidLoad of MyViewController.m, I load the first set of 8 records into my array:

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

In scrollViewDidEndDragging of MyViewController.m, i add next set of 8 records and use the same above mentioned code to add it in the 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];

}

This is my cellForRowAtIndexPath method:

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

    MyObject *myArrayObject = [objAppDelegate.myWishesArray objectAtIndex:indexPath.row];

}

Every time i try to click a row of the table which was visible in my table view, but was just at the end of being loaded, my app gets crashed with the following exception. It may be initial loading or loading more rows as a result of scrolling down the table view. Please keep in mind that when i give the table view enough time to settle and the motion stops and data is fully loaded, then i dont face any exception on clicking the loaded rows.

*** 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'

I have done a lot of research on my problem and found that possible causes of NSRangeException may be:

  • numberOfRowsInSection:(NSInteger)section; method of the UITableView's data source is delivering wrong values.
  • retain should be called on the array.
  • Whenever you modify the underlying data for a table view you need to update the changes by either calling -[UITableView reloadData]; or the beginUpdates and endUpdates methods then adding or removing the correct index paths.

I dont think that my code has first issue. If there is second issue, then where should i make the call to retain myWishesArray? If there is third issue with my code, then how should i proceed to change my code?

Please let me know where i am doing anything wrong. I am stuck on this issue since really long.

Thanks

Edit:

After thorough investigation of the code, i have found the point which is causing this error. I am asynchronously downloading the images in cells of my table view, using the asyncimageview class. Let me paste some code here:

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

Now, myEngine contains the 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];
    }
}

And the AsyncImageView class loads the image using NSURLConnection class. Please note that the app works all ok when i comment this line defined in cellForRowAtIndexPath method:

[self.myEngine loadAsynchronousPhotoAvatarInView:objWish.facebookUserId imageView:cell.contentView];

It does not crash when i click on any row that was loading. Please let me know how should i change my logic. I am not allowed to load the images synchronously, or show any indicator while images are downloading.


Your array with which you are loading your tableview is either not getting filled or is getting released somewhere before you tap on the tableView.

Please add the code where you release your array and Also please make sure that you are synthesizing your array in AppDelegate.

I think there is some issue with the array and not the tableView as array is getting empty.

I hope this helps.


It sounds to me as if your addDataToArray method does not manage to retrieve the data and fill the myWishesArray array before the click is handled. Are you retrieving the data from the web service asynchronously? Is there any way to retrieve all the data at once instead of retrieving it by sections?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜