1and2papa / CTAssetsPickerController

iOS control that allows picking multiple photos and videos from user's photo library.
MIT License
2.15k stars 550 forks source link

showsEmptyAlbums = NO freezes app for tens of seconds if > 10k assets in iCloud #192

Open germs5 opened 8 years ago

germs5 commented 8 years ago

This is even on iOS 9, which honors fetchLimit = 1 in updateAssetCollections.

1and2papa commented 8 years ago

@germs5 Do you have many albums in iCloud?

It's also helpful if you are able to log the time used in each loop iteration in updateAssetCollections.

1and2papa commented 8 years ago

Related #174, #175.

germs5 commented 8 years ago

Actually, there are over 10,000 images, in 1,135 assetCollections, of which only 9 are of type PHCloudSharedAlbum (and containing only 1 or 0 counts of assets), the rest are of type PHAssetCollection. Each assetCollection takes a minimal amount of time. One fetchResult out of 19 takes over 2 seconds, the rest take hundredths of a second.

I think the real issue is that the calculation of updateAssetCollections is performed twice; once for determining if the asset collection should be shown, and again for showing the count. And this is even when fetchLimit = 1 is honored on iOS 9, so the expected slowdown for iOS 8.1 and 8.2 occurs on all platforms.

Attached is the logging of the times through updateAssetCollections, and the code inserts used to generate the logging. The output was massaged to remove any identifying assetCollection information, like the album name.

TenKfreeze.txt

- (void)updateAssetCollections
{
    NSMutableArray *assetCollections = [NSMutableArray new];
    NSMutableArray *gmkfetchDates = [NSMutableArray new]; NSInteger gmkfetchIndex = 0; NSDate *gmkfetchDate;
    NSMutableArray *gmkassetDates = [NSMutableArray new]; NSInteger gmkassetIndex = 0; NSDate *gmkassetDate;
    NSMutableArray *gmkassets = [NSMutableArray new];
    NSMutableArray *gmkcounts = [NSMutableArray new];
    for (PHFetchResult *fetchResult in self.fetchResults)
    {
        gmkfetchDate = [NSDate date];
        for (PHAssetCollection *assetCollection in fetchResult)
        {
            gmkassetDate = [NSDate date];
            BOOL showsAssetCollection = YES;

            if (!self.picker.showsEmptyAlbums)
            {
                PHFetchOptions *options = [PHFetchOptions new];
                options.predicate = self.picker.assetsFetchOptions.predicate;

                if ([options respondsToSelector:@selector(setFetchLimit:)])
                    options.fetchLimit = 1;

                NSInteger count = [assetCollection ctassetPikcerCountOfAssetsFetchedWithOptions:options];

                showsAssetCollection = (count > 0);
                gmkcounts[gmkassetIndex] = @(count);
            }

            if (showsAssetCollection)
                [assetCollections addObject:assetCollection];
            gmkassets[gmkassetIndex] = assetCollection;
            gmkassetDates[gmkassetIndex++] = @(-[gmkassetDate timeIntervalSinceNow]);
        }
        gmkfetchDates[gmkfetchIndex++] = @(-[gmkfetchDate timeIntervalSinceNow]);
    }
    for (NSInteger i = 0; i < gmkassetIndex; ++i) {
        NSLog(@"GMK assetNum:%ld  duration:%@  count:%@  assetCollection:%@", (long)i, gmkassetDates[i], gmkcounts[i], gmkassets[i]);
    }
    for (NSInteger i = 0; i < gmkfetchIndex; ++i) {
        NSLog(@"GMK fetchNum:%ld  duration:%@", (long)i, gmkfetchDates[i]);
    }
    self.assetCollections = [NSMutableArray arrayWithArray:assetCollections];
}
1and2papa commented 8 years ago

@germs5 Thanks for your help. Unfortunately I don't have idea to deal with it right now...

cjkundin commented 8 years ago

Any updates or does anyone know any workarounds for this?

1and2papa commented 8 years ago

Sorry, development of this project is suspended. Please read the home page.