2010-10-16 9 views
3

Continuer à essayer de comprendre les blocs en Objective-C. J'ai la fonction suivante:EXC_BAD_ACCESS si j'appelle directement un bloc Objective-C

typedef void(^TAnimation)(void); 
TAnimation makeAnim(UIView *aView, CGFloat angle, CGFloat x, CGFloat y, 
        CGFloat width, CGFloat height, UIInterfaceOrientation uiio) { 
    return Block_copy(^{ 
     aView.transform = CGAffineTransformMakeRotation(angle); 
     aView.frame = CGRectMake(x, y, width, height); 
     [UIApplication sharedApplication].statusBarOrientation = uiio; 
    }); 
} 

Lorsque je tente de faire ce qui suit:

TAnimation f = makeAnim(...); 
f(); 

je reçois un EXC_BAD_ACCESS. Toutefois, si je fais ce qui suit à la place:

TAnimation f = makeAnim(...); 
[UIView animateWithDuration:0 delay:0 options:0 animations:f completion:NULL]; 

cela fonctionne très bien. Quel est le problème dans le premier scénario?

+1

Dans le débogueur, quelle ligne indique-t-il l'EXC_BAD_ACCESS? –

Répondre

1

Essayez d'utiliser NSZombieEnabled. Lorsque vous libérez un objet, il devient un NSZombie, donc quand vous l'appelez, il lance une exception. Pour activer NSZombieEnabled, ouvrez la fenêtre d'information pour l'exécutable, allez sous Arguments et entrez NSZombieEnable avec une valeur de yes sous "Variables à définir dans l'environnement:".

0

Un exemple à base de blocs très simple comme ceci:

#import <Foundation/Foundation.h> 

typedef void(^printerBlock)(void); 

printerBlock createPrinter(NSString *thingToPrint) { 
    return Block_copy(^{ 
     NSLog(@"Printing: %@", thingToPrint); 
    }); 
} 

int main (int argc, char const* argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    printerBlock pb = createPrinter(@"Testing string."); 
    pb(); 

    [pool drain]; 
    return 0; 
} 

imprime ceci:

2011-10-22 21:28:14.316 blocker[12834:707] Printing: Testing string. 

quand je compilez le programme « bloqueur », donc il doit y avoir une autre raison l'invocation de bloc directe échoue. Certaines raisons peuvent être dues au fait que la vue que vous transmettez est sur-relâchée, auquel cas le conseil de NSZombieEnabled vous aidera.

Si ce n'est pas le cas lorsque la vue est sur-relâchée, alors vous voudrez l'exécuter dans le débogueur et comprendre exactement où les choses se renversent.

Nous devrons probablement voir plus de votre code afin de comprendre ce qui se passe réellement.