Object passed between two (or more) view controllers is a copy not a pointer
I have a number of view controllers which I am passing an object through via properties defined on the sub view and assigning before pushing. I was expecting any changes to the object on the subsequent views to be relected on parent view, and ultimately being reflected on my main view controller from where the chain starts. The object must therefore be copied between the view controllers as a new instance and not passed by reference (pointer).
Code sample... [Just for clarity this code is using UIPopoverController]
SurveyListTableViewController *surveyList = [[SurveyListTableViewController alloc] init]; surveyList.surveys = self.surveys; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:surveyList]; surveyPopoverController = [[UIPopoverController alloc] initWithContentViewController:navController];
Another Code sample... [This sample has a Core Data managed object 'Plan' being passed]
UIStoryboard *storyboard = mainCanvasViewController.storyboard; AddPlanViewController *addPlanViewController = [storyboard instantiateViewControllerWithIdentifier:@"AddPlanViewController"]; addPlanViewController.plan = [NSEntityDescription insertNewObjectForEntityForName:@"Plan" inManagedObjectContext:self.managedObjectContext]; [self.navigationController pushViewController:addPlanViewController animated:YES];
Is there anyway I can force a passing by reference/pointer rather than by value/copy? Or do I need a different approach completely?...
Many thanks in advance. Michael.
If you're passing an object, you are almost always passing a reference to it (not a copy). Passing a copy is actually not very easy.
If you think it's a copy because changes are not reflected in the original, make sure that you're actually storing the changes. It's possible that you're re-assigning values to your object (aka, you're calling initialization every time and resetting the objects) Make sure that you only declare and initialize the objects once.
Honestly, the best strategy would be to just pass a reference to the original class the contains the objects you want to edit and then just work with those. So with your popover controller add a property named something like parentVC. Then inside the popover you could do parentVC.nameOfObject (provided the object is a property of the view controller.
Look at the semantics for the properties that you're setting. Some properties are set to copy the thing they're set to, others to just retain the thing. String properties, for example, are almost always set to copy for two reasons: 1) immutable types like NSString will retain instead of copy anyway, and 2) if someone happens to pass in a mutable string, you usually don't want to change it right under their nose.
Anyway, the most likely reason that you might find yourself dealing with copies instead of the original objects is that the property semantics are set that way. If that turns out to be the issue and the properties are part of your code, then you can obviously change the property declarations to suit your needs. Otherwise, the solution is to let the view controllers in question do their thing, and then retrieve the properties before you dismiss them.