3

I am trying to load associated images from parse into a custom table cell. When I execute the code parse is successfully queried and the other information for the table cell such as book name and author are correctly displayed, but when i try and add in the images the app crashes.

This is the code I use to get the image data.

-(void)queryForNewBooks{
_bookNameArray = [[NSMutableArray alloc] init];

_authorNameArray  = [[NSMutableArray alloc] init];
_isbnNumberArray = [[NSMutableArray alloc] init];
_bookImageData = [[NSMutableArray alloc] init];
PFQuery *query = [PFQuery queryWithClassName:@"BooksForSale"];
[query orderByDescending:@"createdAt"];
[query findObjectsInBackgroundWithBlock:^( NSArray *objects, NSError *error) {

    if (objects.count >=1) {

        for (PFObject *object in objects) {
            PFFile *imageFile = [object objectForKey:@"image"];
            [imageFile getDataInBackgroundWithBlock:^(NSData *result, NSError *error) {
                if (!error) {
                    NSData *data = result;
                    NSLog(@"HEYYYYYY");
                    [ _bookImageData addObject:data];


                }
            }];

Here is the table cell code

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"TableViewCell";

 TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TableViewCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];
}
NSLog(@"Here are the book names, %@",_bookNameArray);

cell.bookNameLabel.text = [_bookNameArray objectAtIndex:indexPath.row];
cell.authorNameLabel.text = [_authorNameArray objectAtIndex:indexPath.row];
UIImage *image = [UIImage imageWithData: [_bookImageData   objectAtIndex:indexPath.row]];
 cell.bookImageLabel.image = image;



return cell;
}

I believe it is these two lines that are causing the issue

  UIImage *image = [UIImage imageWithData: [_bookImageData objectAtIndex:indexPath.row]];
     cell.bookImageLabel.image = image;

when I comment these two line the app doesn't crash.

Can anyone offer suggestions as to what I am doing incorrectly?

Thanks

Error log:

 *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010f951f45 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010f3cbdeb objc_exception_throw + 48
    2   CoreFoundation                      0x000000010f8359e4 -[__NSArrayM objectAtIndex:] + 212
    3   ParseStarterProject                 0x000000010c45fd41 -[ParseStarterProjectViewController tableView:cellForRowAtIndexPath:] + 753
    4   UIKit                               0x000000010dba9e2a -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 782
    5   UIKit                               0x000000010dba9f3f -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
    6   UIKit                               0x000000010db7f307 -[UITableView _updateVisibleCellsNow:isRecursive:] + 3187
    7   UIKit                               0x000000010dbb2d1c -[UITableView _performWithCachedTraitCollection:] + 92
    8   UIKit                               0x000000010db9a884 -[UITableView layoutSubviews] + 223
    9   UIKit                               0x000000010db08e40 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 710
    10  QuartzCore                          0x000000010cf4559a -[CALayer layoutSublayers] + 146
    11  QuartzCore                          0x000000010cf39e70 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
    12  QuartzCore                          0x000000010cf39cee _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
    13  QuartzCore                          0x000000010cf2e475 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277
    14  QuartzCore                          0x000000010cf5bc0a _ZN2CA11Transaction6commitEv + 486
    15  QuartzCore                          0x000000010cf5c37c _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
    16  CoreFoundation                      0x000000010f87d947 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    17  CoreFoundation                      0x000000010f87d8b7 __CFRunLoopDoObservers + 391
    18  CoreFoundation                      0x000000010f87350b __CFRunLoopRun + 1147
    19  CoreFoundation                      0x000000010f872e08 CFRunLoopRunSpecific + 488
    20  GraphicsServices                    0x0000000110f79ad2 GSEventRunModal + 161
    21  UIKit                               0x000000010da5430d UIApplicationMain + 171
    22  ParseStarterProject                 0x000000010c45dfbf main + 111
    23  libdyld.dylib                       0x00000001114fa92d start + 1
    24  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

It appears that the data is not being added to the nsmutablearray which should occur here

for (PFObject *object in objects) {
    PFFile *imageFile = [object objectForKey:@"image"];
    [imageFile getDataInBackgroundWithBlock:^(NSData *result, NSError *error) {
        if (!error) {
            NSData *data = result;
            NSLog(@"HEYYYYYY");
            [ _bookImageData addObject:data];
        }
5
  • You believe it's those two lines? Use the debugger and be sure. See raywenderlich.com/10209/my-app-crashed-now-what-part-1 to learn how to debug a crash. Then update your question with details about the crash including the error message and the exact line that causes the crash. Commented Feb 5, 2016 at 3:27
  • You mentioned that data might not be getting added to _bookImageData. Around that code is an if (!error). Try to log that error: NSLog(@"error: %@", error); to see if that gives you some more hints of the root cause. Commented Feb 5, 2016 at 4:41
  • error comes back as null, when I log out _bookImageData, I get the proper hex code Commented Feb 5, 2016 at 4:45
  • when you reload the table? Can you do that after executing the query for the fetch image from parse. Commented Feb 5, 2016 at 6:13
  • where would be the proper place to reload the data? I think that may be the issue. I tried the code by eliminating all the instances of reload table view and then set that action to a button and the code seemed to execute correctly. I want the table to load right after the data is queried Commented Feb 5, 2016 at 14:58

1 Answer 1

0

getDataInBackgroundWithBlock is an async process. Its need time to receive the response. So before request finished, your _bookImageData is empty array.

Before _bookImageData have data, - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath is being called, and BOOM your app crashed!

 UIImage *image = [UIImage imageWithData: [_bookImageData objectAtIndex:indexPath.row]];
 cell.bookImageLabel.image = image;

The solution is

① Try to refresh your tableview after receive _bookImageData by: [yourtableview reloadData] or something like that.

② Make your app not crash by using try .. catch, or check _bookImageData before your call objectAtIndex.

Recommend: Use some placeHolder image to make your app cooler. :)

   @try {
     UIImage *image = [UIImage imageWithData: [_bookImageData objectAtIndex:indexPath.row]];
     cell.bookImageLabel.image = image;
   } catch ...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.