0

I have an app that organizes text notes. I’m adding the capability to allow photos to be added to a (UITextView) note. I’ve added a subclassed UICollectionViewController to present a users photos from which they can select one to be inserted into their note.

The UICollectionView delegate method below is meant to populate a collection view with photos. I’ve tested this view controller using the apps desktop icon as a test image for ‘photoImage’ and all works fine.

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    PHAsset *asset = (PHAsset *)[fetchResult objectAtIndex:indexPath.row];
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
    options.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;
    options.synchronous = YES;
    NSLog(@" **** calling requestImageForAsset");
    __block UIImage *photoImage;
    __block dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    (void) [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:CGSizeMake(80.0,80.0) contentMode:PHImageContentModeAspectFit options:options
                   resultHandler:^(UIImage *img, NSDictionary *info)
                          {
                            NSError *e = [info objectForKey:PHImageErrorKey];
                            NSLog(@" **** error code (%ld), descr (%@)", (long)e.code, e.localizedDescription);
                            NSLog(@" **** img (%p)", img);
                            photoImage = img;
                            dispatch_semaphore_signal(sema);
                          }
          ];
    NSLog(@" **** returned from requestImageForAsset");
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    dispatch_release(sema);
    UIImageView *photoView = [[UIImageView alloc] initWithImage:photoImage];    <=== Thread 1: EXC_BAD_ACCESS (code=1, address=0x18)
    UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"Photo" forIndexPath:indexPath];
    [cell.contentView addSubview:photoView];

    return cell;

}

My problem is in resultHandler from the requestImageForAsset: call. The Xcode log showing the NSLog() output is below.

2014-12-13 13:18:18.918 iFilebox[23637:866056] **** calling requestImageForAsset 2014-12-13 13:18:18.939 iFilebox[23637:866056] **** error code (0), descr ((null)) <=== no errors reported 2014-12-13 13:18:18.939 iFilebox[23637:866056] **** img (0x7fb4a97b6580) <=== is this a valid memory address? 2014-12-13 13:18:19.940 iFilebox[23637:866056] **** returned from requestImageForAsset

At the point where I want to take the fetched image and add it to a collection view cell, you can see the problem: EXC_BAD_ACCESS. I’ve tried several variations as a workaround to no avail. Again, if I use a known static image in place of the referenced image returned from resultHandler this code works fine.

Can someone explain why this code shouldn’t work, and if it shoulde=, why it doesn’t? Does anyone have any ideas for a workaround?

rm1911
  • 41
  • 1
  • 1
  • 4

1 Answers1

0

even though you set synchronous i am wondering if it is getting to the line where you are tying to instantiate your UIImage photoView before it has actually finished fetching the result you label img. Try just setting the img to the cell.backgroundView in the completion block of the requestImageForAsset and see if that works.

Also, perhaps its just preference, but i would instantiate your cell first, before you do any of this. In fact, you may want to subclass your cell and set the image inside the subclass.

MadeByDouglas
  • 2,509
  • 1
  • 18
  • 22