0

I have an AssetInfo object which I use to encapsulate basic info about an ALAsset or other asset type that I may have in my app.

An asset info keeps the [alAsset thumbnail] as a CGImageRef. When I am checking in instruments I appear to have twice as many CGImage objects than I should. Say there are 4000 AssetInfo instances, I will have about 8000 CGImage instances.

I am instantiating my AssetInfo object as below.

- (void)enumerateAsset:(AssetsGroupInfo *)assetsGroup alAsset:(ALAsset *)alAsset withIndex:(NSUInteger)index {

        NSDate *date = [alAsset valueForProperty:ALAssetPropertyDate];
        NSString *dateKey = [date dateKey];
        CGImageRef thumbnail = [alAsset thumbnail];
        NSURL *url = [[alAsset defaultRepresentation] url];

        AssetInfo *alAssetInfo = [[AssetInfo alloc]
                initWithURL:url
                   withDate:date
              withThumbnail:thumbnail];

        //...
}

My AssetInfo class looks like this

@implementation AssetInfo {
        @private
            NSDate *_dateCreated;
            NSURL *_url;
            CGImageRef _thumbnail;
        }

        - (id)initWithURL:(NSURL *)url withDate:(NSDate *)date withThumbnail:(CGImageRef)thumbnailRef {

            if ((self = [self init])) {
                _url = url;
                _dateCreated = date;
                _thumbnail = CGImageRetain(thumbnailRef);
            }

            return self;
        }

        - (NSURL *)url {
            return _url;
        }

        - (NSDate *)dateCreated {
            return _dateCreated;
        }

        - (CGImageRef)thumbnail {
            return _thumbnail;
        }

        #pragma mark - Equality


        - (BOOL)isEqual:(id)object {

            //TODO:Include date in equality checking
            BOOL valueToReturn = NO;

            if (object && [object respondsToSelector:@selector(url)]) {
                NSURL *myUrl = [self url];
                NSURL *objURL = [object url];
                valueToReturn =  ([myUrl isEqualToURL:objURL]);
            }

            return valueToReturn;
        }

        - (NSUInteger)hash {
            return [[self url] hash];

        }

        - (void)dealloc {

            NSLog(@"%s", __PRETTY_FUNCTION__);

            CGImageRelease(_thumbnail);
        }
    @end

I later use the asset as shown in the code below.

- (void)loadWithAsset:(AssetInfo *)asset {
    _asset = asset;
    _image = [[UIImage alloc] initWithCGImage:[_asset thumbnail]];
}

If I release the thumbnail at the point where I am instantiating the AssetInfo (as shown in snnippet below) the number of living CGImage objects corresponds to the number of living AssetInfo objects. however when I try to access the thumbnail property of the AssetInfo object the app crashes with a EXC_BAD_ACCESS at the line in the above code where I instantiate a UIImage with the CGImageRef.

 - (void)enumerateAsset:(AssetsGroupInfo *)assetsGroup alAsset:(ALAsset *)alAsset withIndex:(NSUInteger)index {

        NSDate *date = [alAsset valueForProperty:ALAssetPropertyDate];
        NSString *dateKey = [date dateKey];
        CGImageRef thumbnail = [alAsset thumbnail];
        NSURL *url = [[alAsset defaultRepresentation] url];

        AssetInfo *alAssetInfo = [[AssetInfo alloc]
                initWithURL:url
                   withDate:date
              withThumbnail:thumbnail];

        //...

      CGImageRelease(thumbnail);
}

Am I doing something wrong?

Jet Basrawi
  • 3,185
  • 2
  • 15
  • 14

1 Answers1

0

I haven't verified, but I would not be surprised if UIImage initWithCGImage: makes a copy. Wouldn't that account for your 2x? In Instruments, look at the stack-trace (extended detail pane on the right) for the living instances. It will tell you who created it.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • This all happens before I use the thumbnail in any UIImage. I simply enumerate the assets in the Assets library and create an object graph representing all the assets there. – Jet Basrawi Aug 29 '12 at 13:57