EXC_BAD_ACCESS invocando un bloque

ACTUALIZAR | He subido un proyecto de muestra usando el panel y fallando aquí:http://w3style.co.uk/~d11wtq/BlocksCrash.tar.gz (Sé que el botón "Elegir ..." no hace nada, aún no lo he implementado).

ACTUALIZACIÓN 2 | Acabo de descubrir que ni siquiera tengo que invocar nada ennewFilePanel Para causar un bloqueo, simplemente necesito usarlo en una declaración.

Esto también provoca un bloqueo:

[newFilePanel beginSheetModalForWindow:[windowController window] completionHandler:^(NSInteger result) {
    newFilePanel; // Do nothing, just use the variable in an expression
}];

Parece que lo último que se arrojó a la consola es a veces esto: "No se puede desmontar dyld_stub_objc_msgSend_stret" y, a veces, esto: "No se puede acceder a la memoria en la dirección 0xa".

He creado mi propia hoja (una subclase de NSPanel), que intenta proporcionar una API similar a NSOpenPanel / NSSavePanel, ya que se presenta como una hoja e invoca un bloque cuando termina.

Aquí está la interfaz:

//
//  EDNewFilePanel.h
//  MojiBaker
//
//  Created by Chris Corbyn on 29/12/10.
//  Copyright 2010 Chris Corbyn. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@class EDNewFilePanel;

@interface EDNewFilePanel : NSPanel <NSTextFieldDelegate> {
    BOOL allowsRelativePaths;

    NSTextField *filenameInput;

    NSButton *relativePathSwitch;

    NSTextField *localPathLabel;
    NSTextField *localPathInput;
    NSButton *chooseButton;

    NSButton *createButton;
    NSButton *cancelButton;
}

@property (nonatomic) BOOL allowsRelativePaths;

+(EDNewFilePanel *)newFilePanel;

-(void)beginSheetModalForWindow:(NSWindow *)aWindow completionHandler:(void (^)(NSInteger result))handler;
-(void)setFileName:(NSString *)fileName;
-(NSString *)fileName;
-(void)setLocalPath:(NSString *)localPath;
-(NSString *)localPath;
-(BOOL)isRelative;

@end

Y los métodos clave dentro de la implementación:

-(void)beginSheetModalForWindow:(NSWindow *)aWindow completionHandler:(void (^)(NSInteger result))handler {
    [NSApp beginSheet:self
       modalForWindow:aWindow
        modalDelegate:self
       didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
          contextInfo:(void *)[handler retain]];
}

-(void)dismissSheet:(id)sender {
    [NSApp endSheet:self returnCode:([sender tag] == 1) ? NSOKButton : NSCancelButton];
}

-(void)sheetDidEnd:(NSWindow *)aSheet returnCode:(NSInteger)result contextInfo:(void *)contextInfo {
    ((void (^)(NSUInteger result))contextInfo)(result);
    [self orderOut:self];
    [(void (^)(NSUInteger result))contextInfo release];
}

Todo esto funciona siempre que mi bloque sea solo un no-op con un cuerpo vacío. Mi bloqueo se invoca cuando se descarta la hoja.

EDNewFilePanel *newFilePanel = [EDNewFilePanel newFilePanel];
[newFilePanel setAllowsRelativePaths:[self hasSelectedItems]];
[newFilePanel setLocalPath:@"~/"];
[newFilePanel beginSheetModalForWindow:[windowController window] completionHandler:^(NSInteger result) {
    NSLog(@"I got invoked!");
}];

Pero tan pronto como intento acceder al panel desde el interior del bloque, me cuelgo con EXC_BAD_ACCESS. Por ejemplo, esto se bloquea:

EDNewFilePanel *newFilePanel = [EDNewFilePanel newFilePanel];
[newFilePanel setAllowsRelativePaths:[self hasSelectedItems]];
[newFilePanel setLocalPath:@"~/"];
[newFilePanel beginSheetModalForWindow:[windowController window] completionHandler:^(NSInteger result) {
    NSLog(@"I got invoked and the panel is %@!", newFilePanel);
}];

No está claro del depurador con la causa. El primer elemento (cero 0) en la pila solo dice "??" Y no hay nada en la lista.

Los siguientes elementos (1 y 2) en la pila son las llamadas a-endSheet:returnCode: y-dismissSheet: respectivamente. Mirando a través de las variables en el depurador, nada parece estar fuera de alcance.

Pensé que tal vez el panel había sido lanzado (ya que se lanzó automáticamente), pero incluso llamé-retain en él justo después de crearlo no ayuda.

¿Estoy implementando esto mal?

Respuestas a la pregunta(2)

Su respuesta a la pregunta