3

继续尝试理解 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;
    });
}

当我尝试执行以下操作时:

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

我得到一个 EXC_BAD_ACCESS。但是,如果我改为执行以下操作:

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

它工作正常。第一种情况有什么问题?

4

2 回答 2

1

尝试使用 NSZombieEnabled。当你释放一个对象时,它会变成一个 NSZombie,所以当你调用它时,它会抛出一个异常。要激活 NSZombieEnabled,打开可执行文件的信息窗口,在 Arguments 下输入 NSZombieEnable,在“Variables to be set in the Environment:”下输入值为 yes。

于 2011-07-04T14:30:25.727 回答
0

一个非常简单的基于块的示例,如下所示:

#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;
}

打印出来:

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

当我将程序编译为“阻止程序”时,直接块调用失败肯定有其他原因。一些原因可能是因为您传入的视图被过度发布,在这种情况下,NSZombieEnabled 建议将帮助您。

如果不是视图被过度释放的情况,那么您将需要在调试器中运行它并准确找出问题所在的位置。

我们可能需要查看更多您的代码才能弄清楚实际发生了什么问题。

于 2011-10-23T04:32:10.917 回答