使用块时的iPhone EXC_BAD_ACCESS

Mad*_*sen 5 iphone cocoa-touch objective-c

我试图使用块创建一个简单的回调.我有一个MainViewController addSubView另一个DatePickerViewController.view我创建了一个像这样的块

typedef void(^DateChangedBlock)(NSDate*);
Run Code Online (Sandbox Code Playgroud)

我在我的DatePickerViewController上调用了一个方法

setOnDateChangedCallback:(DateChangedBlock)callback
Run Code Online (Sandbox Code Playgroud)

我将回调存储在DatePickerViewController的属性中.DatePickerViewController的视图是一个UIDatePicker实例,我已将IBAction绑定到更改为执行此操作的方法的值.

- (IBAction)dateChanged:(id)sender {

    if (dateChangedCallback != nil)
    {
        dateChangedCallback(nil);
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是我在MainViewController中注册块的方法

DatePickerViewController *dateController = [[DatePickerViewController alloc] initWithNibName:@"DatePickerView" bundle:nil];

self.datePicker = dateController;
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 100, 200)];
[self.view addSubview:textView];
DateChangedBlock myBlock = ^(NSDate *newDate) {
 textView.text = @"testing";
};

[self.datePicker setOnDateChanged: myBlock];
[self.datePicker dateChanged:self]; // force trigger (this works).
Run Code Online (Sandbox Code Playgroud)

当我强制触发DatePickerViewController上的dateChanged方法时,它没有问题.但是当datepicker本身通过IBAction触发方法时,我得到一个EXC_BAD_ACCESS错误.此方法在"int retVal"行上发生错误.

#import <UIKit/UIKit.h>

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil); // THREAD 1: program received EXC_BAD_ACCCESS.**
    [pool release];
    return retVal;
}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Eim*_*tas 24

您应该在将块传递给其他方法时复制块(例如在您的情况下使用属性设置器).因此,在设置回调块时,请执行以下操作:

[self.datePicker setOnDateChanged:[[myBlock copy] autorelease]];
Run Code Online (Sandbox Code Playgroud)

您在创建块时使用的EXC_BAD_ACCESS原因块变量不会被块本身保留.因此,当调用块时 - 变量不再存在.