0

I have an app which is based on storyboard based with UINavigationController. I have three views A, B, C. I am starting camera in View A when user hits a camera button , after successfully clicking image and getting that image I am calling segue to go to B which is a PUSH segue. In view B I am showing image with an option to process image. When user selects to process it goes to view C with a PUSH segue. Now what i want is after processing the image should be sent back to view B where I will show processed image.

Problem is when I pass the image back from C to B using a pointer to B (delegate) app crashes. Code is as below

In view B to pass image to view C:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"Segue1"])
    {
        // Get reference to the destination view controller
        CViewController *vc = [segue destinationViewController];

        // Pass any objects to the view controller here, like...
        vc.imageChosen = imageChosen;
        vc.delegate = self;
    }
}

delegate is declared in CViewController as follows:

@property (nonatomic,retain) id delegate;

In view controller C to return image back, I'm doing following

-(IBAction)actionBack
{
    BViewController *vc = (BViewController *)delegate;
    vc.imageChosen = imageCropped;

    [self.navigationController popViewControllerAnimated:TRUE];

}

actionBack is a selector attached to back button on view C

App crashes with EXC_BAD_ACCESS on a line in BViewController.h which is as follows

@property (nonatomic,retain) UIImage *imageChosen;

I have checked imageCropped has valid data which i tried saving to gallery as well imageCropped is a property in CViewController with following declaration

@property (nonatomic,retain) UIImage *imageCropped;

I'm not understanding why this is crashing and assistance would be appreciated.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
vishal dharankar
  • 7,536
  • 7
  • 57
  • 93
  • 1
    1) Can you provide app crash log? 2) @property (nonatomic,retain) id delegate; - this is bad practice, use assaign or weak modifier instead – frankWhite Nov 26 '13 at 21:03
  • No problem isn't with delegate it's giving me access to view controller right it's the imagechosen property that causes bad access – vishal dharankar Nov 27 '13 at 05:50
  • @vishal Actually, the error you describe _can_ be a result of problems with the `delegate` (and your use of the `delegate` ivar in `actionBack` is a little bit suspicious ... usually you'd refer to the getter method, or you'd refer to an ivar with leading underscore). Bottom line, you haven't shown us enough to dismiss the possibility that the `delegate` might not be a problem. – Rob Nov 27 '13 at 19:34
  • 1
    Are you using ARC? If so, use `strong` instead of `retain` and `weak` instead of `assign`. If not, turn on zombies and make sure you're not over releasing the object in question. – Rob Nov 27 '13 at 20:20

2 Answers2

1

A couple of thoughts:

  1. You suggest you're getting a EXC_BAD_ACCESS at the line in B that defines imageChosen.

    @property (nonatomic,retain) UIImage *imageChosen;
    

    That's unlikely. You don't get EXC_BAD_ACCESS at the line at which you defined the property, but rather the line at which you attempt to use that property or its associated ivar. And you presumably reference this in multiple places, so you really should identify the offending line of code. Rather than us guessing at which line this EXC_BAD_ACCESS is happening, you should probably turn on exception breakpoints and or carefully look at the stack trace to identify precisely where the exception is taking place.

  2. Since you're messing around in manual retain and release code, you really should:

    • Run the code through the static analyzer ("Analyze" on the Xcode "Product" menu), and make sure you fix any and all warnings you get there.

    • Temporarily turn on zombies, so that you can correctly identify any overrelease of items.

  3. You didn't show us how you defined delegate property. I only mention that because you are setting the delegate property, but C proceeds to use a delegate instance variable (and modern convention is that your ivars should have leading underscore, e.g. _delegate). You can do it the way you've suggested in your code snippet, but if not done precisely correctly, it's susceptible to a particular series of conditions that can produce the crash you describe.

    Personally, I'd advise that (a) you make sure you do not have not explicitly declared ivar for delegate (just define the property and let the ivar be synthesized); (b) exclude any explicit @synthesize statement (but rather let it be synthesized automatically); and (c) use the accessor methods where possible.


Unrelated to your crash, but you have a retain cycle here. The delegate in C that refers back to B should be assign, not retain (or if you were using ARC, weak rather than strong). You'll have a retain cycle the way it's currently written and, as a result, you will leak.

Also, as a matter of good style, you should also probably use a protocol, but that's not critical.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

I'm better use some method in delegate to provide image to it.

Something like this:

if (_delegate && [_delegate respondsToSelector:@selector(passImage:)])
{
    [_delegate passImage:imageCropped];
}

and in delegate itself:

- (void)passImage:(UIImage *)img
{
    // do something
}

Hope it'll help you.

Denis Kozhukhov
  • 1,205
  • 8
  • 16
  • I have used a method using delegate from here now http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers I am passing image from View C to View B successfully assigning it to a variable but whenever I try to access that image it says again BAD ACCESS Thread 1. – vishal dharankar Nov 27 '13 at 19:08