1

I have simple app with two views: the first view has a button, and when you press it you get a modal segue to another view. As you know, the controller popped out with a modal segue doesn't have a "Back" button, so you probably write delegates. I want to use blocks for more compact code. Firstl I did the following.

Declare block in "Second" view controller:

typedef void (^SecondViewControllerCompletionBlock)(BOOL success);

@interface SecondViewController : UIViewController

@property (nonatomic, copy) SecondViewControllerCompletionBlock CompletionBlock;

I wrote code in a "Done" button's action (which is the button on top of the UINavigationController):

- (IBAction)doneBarButton:(id)sender {

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

}

Preparing in the "First" view controller for 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];
        }
    };

}

So, everything works just fine; I can close the menu by pressing the done button. But what if I want something other than BOOL when declaring the block? I tried using an int.

Declaring the block:

typedef void (^SecondViewControllerCompletionBlock)(int success);

@interface SecondViewController : UIViewController

@property (nonatomic, copy) SecondViewControllerCompletionBlock CompletionBlock;

Changing the code in the doneBarButtonItem: action method:

- (IBAction)doneBarButton:(id)sender {

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

}

In this method when I wrote an if statement, I placed 2 in round brackets as the argument, but, my point was, if you put here anything except 1 (which I pass when configuring the action method), the statement should not execute, so, controller should not close. But it does, in all cases, if I put 1 in if(1) statement, or 2, or anything else.

-(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];
            }
        };

}

I might be missing something obvious. Can you help me fix this? It would be nice to have not only BOOL for changing actions.

4

1 回答 1

1
if (2) {
    ...
}

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

if (YES) {
    ...
}

显然,它总是通过。

您真正想要的是针对该值测试参数:

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

最后,文体说明:所有变量都应以小写字母开头,块变量也不例外。CompletionBlock应该命名completionBlock,而不是。

于 2013-11-02T19:53:43.907 回答