0

I'm making a non-garbage-collected MacFUSE Cocoa application, inside of which I want to use a GCD block as a delegate. However, my program crashes during the invocation of the block, leaving only an EXC_BAD_ACCESS in its trail.

My program uses a framework built agains the Mac OS 10.5 SDK that does not support garbage collection (nor 64 bits) and the MacFUSE framework. The program builds with no warning or error as a 32-bit program. Other build settings (such as optimization level) were left to their original values.

So I have my application controller, from which I create this block and call runWithContinuation:

AFSPasswordPrompt* prompt = [[AFSPasswordPrompt alloc] initWithIcon:icon];
dispatch_block_t continuation = ^{
    archive.password = prompt.password;
    [self mountFilesystem:fsController];
    [prompt performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
};
[prompt runWithContinuation:continuation];

runWithContinuation: retains the block and instantiates a nib. The block is called only once the user dismisses the password prompt by pressing the "Open" button.

-(void)runWithContinuation:(dispatch_block_t)block
{
    continuation = [block retain];
    [passwordPrompt instantiateNibWithOwner:self topLevelObjects:NULL];
    imageView.image = image;
    [window makeKeyWindow];
}

-(IBAction)open:(id)sender
{
    continuation();
    [self close];
}

-(void)close
{
    [window close];
    [continuation release];
}

My problem is that when I hit continuation(), my program triggers an EXC_BAD_ACCESS, and the last stack frame is called ??. Right under it is the open: method call.

I really don't know where it's coming from. NSZombies are enabled, and they don't report anything.

Any ideas?

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
zneak
  • 134,922
  • 42
  • 253
  • 328

1 Answers1

2

try copying the block instead of retaining it. A block lives on the stack until you call copy, then it is copied to the heap.

cobbal
  • 69,903
  • 20
  • 143
  • 156
  • Do I also have to retain it in order to survive the `NSAutoreleasePool`? – zneak Nov 18 '10 at 05:07
  • @zneak copy, like retain, means that you now own the object. So you don't need an additional retain. – cobbal Nov 18 '10 at 05:08
  • 1
    See "Patterns to Avoid" (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Blocks/Articles/bxUsing.html%23//apple_ref/doc/uid/TP40007502-CH5-SW6) for more information. – Nicholas Riley Nov 18 '10 at 05:11