2

我第一次尝试使用 Objective C 块,因为我非常喜欢在 Python 和 Haskell 等语言中使用闭包。

我遇到了一个问题,但是我希望有人可以提供帮助。

以下是我遇到的问题的最简单版本。

typedef void(^BlockType)(NSString *string);

- (void)testWithtarget:(id)target action:(SEL)action
{
    BlockType block = ^(NSString *string) {
        [target performSelector:action withObject:data];
    };

    block(@"Test String"); // Succeeds

    [self performSelector:@selector(doBlock:) withObject:block afterDelay:5.0f];
}

- (void)doBlock:(BlockType)block
{
    block(@"Test String 2"); // Causes EXC_BAD_ACCESS crash
}

所以这似乎是某种内存管理问题,这并不让我感到惊讶,但我只是没有看到解决方案的知识。可能我正在尝试的事情甚至不可能。

有兴趣看看其他人的想法:)

4

1 回答 1

5

该块不会被保留,因为它只存在于堆栈中。afterDelay:如果您想在当前堆栈范围之外使用它(即因为您正在使用),您需要复制它。

- (void)testWithtarget:(id)target action:(SEL)action
{
    BlockType block = ^(NSString *string) {
        [target performSelector:action withObject:data];
    };

    block(@"Test String"); // Succeeds

    [self performSelector:@selector(doBlock:) withObject:[block copy] afterDelay:5.0f];
}

- (void)doBlock:(BlockType)block
{
    block(@"Test String 2");
    [block release];
}

但是,由于您要跨方法调用进行复制和释放,因此这有点冒险,但是在这种特定情况下,您需要这样做。

于 2011-01-07T01:32:35.653 回答