1

我在一个类中定义了一个块:

BXButton.h

typedef void(^ButtonClicked)(id sender, NSDictionary *userInfo);
@property (assign, nonatomic) ButtonClicked onButtonClicked;
- (void)setClickBlock:(ButtonClicked)buttonClicked;

BXButton.m

- (void)setClickBlock:(ButtonClicked)buttonClicked {
    onButtonClicked = buttonClicked;
}
- (void)internalButtonClicked {
    DLog(@"internal clicked");
    if (self.onButtonClicked) {
        onButtonClicked(self, self.userInfo);
    }
}

我试图在视图控制器中这样调用:

[_testButton setClickBlock:^(BXButton *sender, NSDictionary *userInfo) {
        DLog(@"userInfo %@", userInfo);
        [sender startLoading];
        [[BXAPIClient sharedPublicClient]postPath:@"/" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            [sender endLoading];
            //[safeSelf stop];
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            [sender endLoading];
            [self stop];
        }];
    }];

每当我尝试访问 [self 方法] 或在块之外定义的任何变量时,我总是得到 BAD_ACCESS。有任何想法吗?谢谢!

4

1 回答 1

11

你得到的原因EXC_BAD_ACCESS是因为默认情况下在堆栈上创建块,所以如果你用一个assign属性引用它们,当堆栈被拆除时它们将不再存在。

为了解决这个问题,您应该将块复制到堆中。一种方法是在定义属性时使用copy而不是。assign

将您的声明更改为

@property(copy, nonatomic) ButtonClicked onButtonClicked;

并在分配块时使用它的 setter/getter 而不是直接访问 ivar

- (void)setClickBlock:(ButtonClicked)buttonClicked {
    self.onButtonClicked = buttonClicked;
}
- (void)internalButtonClicked {
    DLog(@"internal clicked");
    if (self.onButtonClicked) {
        self.onButtonClicked(self, self.userInfo);
    }
}
于 2012-12-11T04:34:10.503 回答