0

I'm using blocks to pass data from a view controller, VC3, which appears within a modal view that is pushed by VC1. The modal displayed is VC2, and it shows VC3 before being dismissed.

I am getting a EXC_BAD_ACCESS error when using the blocks.

Below is the code.

VC1.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
self.VC2 = [storyboard instantiateViewControllerWithIdentifier:@"VC2"];

VC3 *VC3 = [storyboard instantiateViewControllerWithIdentifier:@"VC3"];

VC3.onDismiss = [^(VC3 *sender, NSMutableArray *details)
{
    //set stuff here

} copy];
[self presentViewController:VC2 animated:YES completion:nil];

VC3.h

@property (nonatomic, strong) void (^onDismiss)(VC3 *sender, NSMutableArray* details);

VC3.m

 [self dismissViewControllerAnimated:YES completion:^{
   NSMutableArray *details = [NSMutableArray array];
    [details addObject:x];
    [details addObject:y];
    [details addObject:z];

    self.onDismiss(self, details);
}];

I've tried and failed to get this working a few times. If someone could help me with this, I would be really grateful.

emleeh
  • 106
  • 1
  • 5
  • 1
    you should check that a block isn't `nil` before calling it. If it is, it will crash when called. – Hamish Feb 29 '16 at 21:49
  • @originaluser2 I've done that and it has stopped it from crashing, but now the block in VC1 is never called now. – emleeh Feb 29 '16 at 22:14

1 Answers1

0
  1. Block properties should be declared as copy

    @property (nonatomic, copy) void (^simpleBlock)(void);
    
  2. Then, when passing the block, don't call the copy method on it.

    VC3.onDismiss = ^(VC3 *sender, NSMutableArray *details)
    {
        // do stuff here
    };
    
  3. Finally, you should check if the block is not nil before executing it.

Problem

It looks like you're invoking the block after the view controller was dismissed. This means you're trying to access deallocated memory. Problem lays here:

 [self dismissViewControllerAnimated:YES completion:^{
   NSMutableArray *details = [NSMutableArray array];
    [details addObject:x];
    [details addObject:y];
    [details addObject:z];

    self.onDismiss(self, details);
}];

You dismiss the controller and then in completion handler you access it's property.

Rafał Sroka
  • 39,540
  • 23
  • 113
  • 143
  • Thanks for the response, but I've done all those changes and am still getting the error! – emleeh Feb 29 '16 at 22:12
  • Alright, I think I figured it out. Please check out updated answer. – Rafał Sroka Feb 29 '16 at 22:16
  • Ah yes, that's a really good point. I've moved the self.onDismiss(self, details) call so that it is outside of the completion block, but it is still 'nil'. Perhaps its because I don't define it in the VC3.m? Or would that be an issue? – emleeh Feb 29 '16 at 22:19