Question

I have a program where I set up a completion block that is running on a background thread. Inside the block I set up a CGImageRef and then on the main thread set my layer contents. THe problem is, sometimes the app crashes on the main thread portion.

This is the completion block, in the code below both the fullImage and cfFullImage are declared in my .h

requestCompleteBlock completionBlock = ^(id data)
{
    // Seems I need to hold onto the data for use later
    fullImage = (NSImage*)data;
    NSRect fullSizeRect = NSMakeRect(0, 0, self.frame.size.width, self.frame.size.height);

    // Calling setContents with an NSImage is expensive because the image has to
    // be pushed to the GPU first. So, pre-emptively push it to the GPU by getting
    // a CGImage instead.
    cgFullImage = [fullImage CGImageForProposedRect:&fullSizeRect context:nil hints:NULL];

    // Rendering needs to happen on the main thread or else crashes will occur
    [self performSelectorOnMainThread:@selector(displayFullSize) withObject:nil waitUntilDone:NO];
};

The final line of my completion block is to call displayFullSize. That function is below.

- (void)displayFullSize
{
    [self setContents:(__bridge id)(cgFullImage)];
}

Do you see or know of any reason why the setContents might fail?

Thanks Joe

Was it helpful?

Solution

cgFullImage is not retained. The CGImage Core Foundation object is deallocated and you are using a deallocated object.

Core Foundation object pointer types like CGImageRef are not managed by ARC. You should either annotate the instance variable with __attribute__((NSObject)), or change the type of the instance variable to an Objective-C object pointer type like id.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top