正确使用块进行两个类之间的回调

时间:2013-11-02 19:00:31

标签: ios objective-c objective-c-blocks

我有两个视图的简单应用程序:第一个视图有一个按钮,当你按下它时,你得到一个模态segue到另一个视图。如你所知,控制器突然出现模态segue没有“后退”按钮,所以你可能会写代表。我想使用块来获得更紧凑的代码。首先,我做了以下事情。

在“第二个”视图控制器中声明块:

typedef void (^SecondViewControllerCompletionBlock)(BOOL success);

@interface SecondViewController : UIViewController

@property (nonatomic, copy) SecondViewControllerCompletionBlock CompletionBlock;

我在“完成”按钮的操作(这是UINavigationController顶部的按钮)中编写了代码:

- (IBAction)doneBarButton:(id)sender {

    if (self.CompletionBlock !=nil){
        self.CompletionBlock (YES);
    }

}

在“First”视图控制器中准备segue:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{



    if ([segue.identifier isEqualToString:@"ShowDetail"]){

     __weak SecondViewController *controller = segue.destinationViewController;
     controller.CompletionBlock = ^(BOOL success){

         if (NO){
            [self dismissViewControllerAnimated:YES completion:nil];
        }
    };

}

所以,一切都很好;我可以按完成按钮关闭菜单。但是如果我在声明块时需要BOOL之外的其他内容呢?我尝试使用int

声明阻止:

typedef void (^SecondViewControllerCompletionBlock)(int success);

@interface SecondViewController : UIViewController

@property (nonatomic, copy) SecondViewControllerCompletionBlock CompletionBlock;

更改doneBarButtonItem:操作方法中的代码:

- (IBAction)doneBarButton:(id)sender {

    if (self.CompletionBlock !=nil){
        self.CompletionBlock (1);
    }

}

在我编写if语句的方法中,我将2放在圆括号中作为参数,但是,我的观点是,如果你放在1以外的任何东西(其中)我在配置动作方法时通过),语句不应该执行,因此,控制器不应该关闭。但是,在所有情况下,如果我将1放入if(1)语句,或2或其他任何内容,它确实存在。

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    if ([segue.identifier isEqualToString:@"ShowDetail"]){

        __weak SecondViewController *controller = segue.destinationViewController;
        controller.CompletionBlock = ^(int success){

            if (2){
               [self dismissViewControllerAnimated:YES completion:nil];
            }
        };

}

我可能会遗漏一些明显的东西。你能帮我解决这个问题吗?不仅BOOL可以改变行动,还不错。

1 个答案:

答案 0 :(得分:1)

if (2) {
    ...
}

没什么意义。在C(和Objective-C)中,任何非零值的计算结果为true,因此您所做的测试大致相当于

if (YES) {
    ...
}
显然,它总是过去。

你真正想要的是测试反对该值的论据:

controller.CompletionBlock = ^(int success){
    if (success == 2){
        [self dismissViewControllerAnimated:YES completion:nil];
    }
};

最后,一个风格的评论:所有变量都应该以小写字母开头,而块变量也不例外。 CompletionBlock应该命名为completionBlock