[PHCollectionList canContainCustomKeyAssets]: в экземпляр отправлен нераспознанный селектор

При получении PHAssets у меня теперь происходит сбой в последних версиях iOS (iOS 9.2 и iOS 9.3). Раньше работал нормально.

Ошибка, которую я получаю:

[PHCollectionList canContainCustomKeyAssets]: нераспознанный селектор отправлен экземпляру. Завершение приложения из-за необработанного исключения «NSInvalidArgumentException»

Строка, вызывающая исключение:

            PHFetchResult *fetchImage = [PHAsset fetchKeyAssetsInAssetCollection:(PHAssetCollection*)collection options:fetchOptions];

Вот еще код, для справки:

Class PHPhotoLibrary_class = NSClassFromString(@"PHPhotoLibrary");
        if (PHPhotoLibrary_class) {

            PHFetchResult *fetchResult = self.collectionsFetchResults[indexPath.section];
            PHCollection *collection = fetchResult[indexPath.row];

            cell.textLabel.text = collection.localizedTitle;

            PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
            fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
            PHFetchResult *fetchImage = [PHAsset fetchKeyAssetsInAssetCollection:(PHAssetCollection*)collection options:fetchOptions];
            PHAsset *asset = [fetchImage firstObject];

            PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
            options.resizeMode = PHImageRequestOptionsResizeModeExact;

            CGFloat scale = [UIScreen mainScreen].scale;
            CGFloat dimension = 90.0;
            CGSize size = CGSizeMake(dimension*scale, dimension*scale);

            [[PHImageManager defaultManager] requestImageForAsset:asset
                                                       targetSize:size
                                                      contentMode:PHImageContentModeAspectFill
                                                          options:options
                                                    resultHandler:^(UIImage *result, NSDictionary *info) {
                                                        if (result) {
                                                            CGSize itemSize = CGSizeMake(60, 60);
                                                            UIGraphicsBeginImageContextWithOptions(itemSize, NO, 2);
                                                            CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
                                                            [result drawInRect:imageRect];
                                                            cell.imageView.image  = UIGraphicsGetImageFromCurrentImageContext();
                                                            UIGraphicsEndImageContext();
                                                        }
                                                        else{
                                                            UIImage *placeholder = [UIImage imageNamed:@"image-placeholder.jpg"];
                                                            CGSize itemSize = CGSizeMake(60, 60);
                                                            UIGraphicsBeginImageContextWithOptions(itemSize, NO, 2);
                                                            CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
                                                            [placeholder drawInRect:imageRect];
                                                            cell.imageView.image  = UIGraphicsGetImageFromCurrentImageContext();
                                                            UIGraphicsEndImageContext();
                                                        }
                                                    }];
        }

person William GP    schedule 14.04.2016    source источник


Ответы (2)


Эта проблема на самом деле лежит здесь:

PHCollection *collection = fetchResult[indexPath.row];

а потом сюда:

PHAsset *asset = [fetchImage firstObject];

Вы извлекаете коллекцию, используя PHCollection, а затем просто предполагаете, что все активы являются PHAssets, не проверяя должным образом, так это или нет.

На самом деле PHCollection имеет два возможных подкласса: PHAsset и PHCollectionList, и PHCollectionList - это то, что выдает здесь ошибку.

Оберните код после PHCollection *collection = fetchResult[indexPath.row]; проверкой на PHAsset, и это должно решить проблему:

if ([collection isKindOfClass:[PHAssetCollection class]]) {
//code 
}
person William GP    schedule 20.04.2016
comment
Я знаю, что это довольно старо, но у меня только что появилось это точное исключение в моем приложении, и мне было интересно, есть ли надежный способ вызвать эту проблему. - person lyio; 16.11.2020

Во-первых, получите все активы, используя PHAsset, например

dispatch_async(dispatch_get_main_queue(), ^{     

        AllPhotos=[[NSMutableArray alloc] init];
        PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];
        for (PHAsset *asset in result)
        {
            [AllPhotos addObject:asset];

        }
        [self.collectionView reloadData];

        // code here
    });

Нет, используйте метод делегата collectionview, например

  PHImageManager *manager = [PHImageManager defaultManager];
    PHAsset *asset = [AllPhotos objectAtIndex:indexPath.row];
    PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
    requestOptions.resizeMode   = PHImageRequestOptionsResizeModeExact;
    requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
    requestOptions.synchronous = false;

    //CGFloat scale = 1.5; //or an even smaller one
    if (!manager)
    {
        manager = [[PHCachingImageManager alloc] init];
    }
    if (!requestOptions)
    {
        requestOptions = [[PHImageRequestOptions alloc] init];
    }

    [manager requestImageForAsset:asset
                       targetSize:CGSizeMake(imagesize.width,imagesize.height)
                      contentMode:PHImageContentModeAspectFill
                          options:requestOptions
                    resultHandler:^void(UIImage *image, NSDictionary *info)
     {
         [imageview setImage:image];
     }];

    [cell.contentView addSubview:imageview];
person Ishwar Hingu    schedule 19.04.2016