0

I have a navigation controller with 2 view controllers, A and B.

A and B both have a property

@property (strong, nonatomic) NSString *string;

string is created in controller A and passed to controller B

ViewControllerB.string = self.string;
[self.navigationController pushViewController:ViewControllerB];

In View Controller B, string is modified and when I pop to View Controller A, the value of string has not changed.

Since they both hold a strong reference to it, shouldn't string be changed in both View Controllers?

Am I missing something?

stefano_cdn
  • 1,362
  • 2
  • 15
  • 29
  • In that setup I think the best way to handle it is either delegates or possibly using a block. I will try to post some examples later. – logixologist Jul 14 '15 at 20:07
  • Sounds to me like the confusion you're having is due to misunderstanding the distinction between passing by-reference vs. by-value. See this link for more details: http://stackoverflow.com/questions/2892520/passing-arguments-by-value-or-by-reference-in-objective-c – Mike Jul 14 '15 at 20:16

1 Answers1

2

In View Controller B, string is modified

This is impossible since you're using NSString, not NSMutableString. If you replace it within ViewControllerB:

self.string = @"some other string";

Then you are setting ViewControllerB's string property to reference that new string, but other references to the original string are not affected.

If you really want both view controllers to modify the same string, use NSMutableString. But shared mutable state is probably bad. Instead, consider using an intermediary class (like a data source), or the delegate pattern for ViewControllerB to hand ViewControllerA an updated string.

Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
  • I got the impression the issue here isn't the modification of the string, which I'm guessing was done by just setting it equal to another string, but rather a by-reference vs. by-value problem... – Mike Jul 14 '15 at 20:15
  • The issue is that VCA has a reference to the old string and VCB has a reference to the new string. The OP wants VCB's new string to propagate back to VCA, but since VCB is creating a new string instead of modifying the existing one, that won't happen. – Aaron Brager Jul 14 '15 at 20:16
  • Like I said, that is because the string is passed by-value where it seems like he expects it to act like it was passed by-reference. Why would changing it to an instance of NSMutableString solve the issue? – Mike Jul 14 '15 at 20:18
  • @Mike Using `NSMutableString`, the OP could modify the same string object with the new data. VCA and VCB would both have references to the same mutable string. – Aaron Brager Jul 14 '15 at 20:30
  • If they share the same reference, the fact that its mutable or not makes less difference, depending exactly what OP means by "modify". If he means `string = @"anotherString"`, making it mutable makes no difference. I'm not really in disagreement with you on the solution, but the focus of your answer seems to be on the mutability of the string where I personally think the by-ref/by-val is where he's likely most confused, based on the question. If he's trying to modify a normal string in the same way you would a mutable one, he'll get a different set of warnings/errors anyway. – Mike Jul 14 '15 at 20:39
  • @Mike Right, I think we agree. Replacing a string as in your example, wouldn't make a difference if the string was mutable, but I didn't want to add sample code to explain that because I didn't want to encourage that approach. – Aaron Brager Jul 14 '15 at 20:41
  • BTW, I would happily accept any suggested edits to my answer. – Aaron Brager Jul 14 '15 at 20:41