Reputation: 7749
I cant wrap my head around this for some reason...
I have a class (Model) with an ivar (value). I want to pass the value to a method and change the value ivar to point to something else. This changes the aValue to point to newString. So, how do I get the model.value to point to newString with out saying model.value = newString
?
(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
Model * model = [[Model alloc] init];//model.value gets set in init
[self doSomething:model.value];
NSLog(@"changed? %@", model.value);
}
- (void)doSomething:(NSString *)aValue
{
NSString * newString = [[NSString alloc] initWithString:@"new string"];
aValue = newString;
NSLog(@"changed? %@", aValue);
}
Also, how do I get this darn code block to work right?
Upvotes: 1
Views: 207
Reputation: 20048
What's wrong with updating the property using model.value=newString
? If you really want doSomething:
to modify its string parameter, you need to pass a pointer to the variable:
- (void)doSomething:(NSString **)aValue
{
[*aValue release];
NSString * newString = [[NSString alloc] initWithString:@"new string"];
*aValue = newString;
NSLog(@"changed? %@", *aValue);
}
and call it like this:
[self doSomething:&value];
But this is not very idiomatic. It is probably cleaner to just return a value and let the caller decide how to manage the result:
- (NSString*)doSomething
{
NSString * newString = [[NSString alloc] initWithString:@"new string"];
NSLog(@"changed? %@", *aValue);
return [newString autorelease];
}
Upvotes: 1
Reputation: 187272
You need to pass in a pointer to the ivar, and not the ivar itself.
[self doSomething:&model.value];
And create your method like so:
- (void)doSomething:(NSString**)aValue {
*aValue = @"new string";
}
So when you do
NSString *foo = @"old string";
[self doSomething:&foo];
NSLog(@"foo is: %@", foo);
foo
's value is @"new string"
.
You are accepting the pointer to the object, and making it point to a different object. Normally, the function gets it's own pointer and you assigning a new value to it has no effect outside of the scope that created it.
I'm actually not sure what this is officially called, but I am pretty sure this is how it works. Anyone more well versed in C can likely clarify.
And, of course, this example is easily cleaned by simply returning a value. This trick is useful, but I think in most cases your code will be easier to understand and overall cleaner if you avoid this pattern. So only use it if you have a good reason, like you have a method returning a value, but also want to return more values that may or may not be important that the caller can optionally capture. But if you can simply return a value and assign it, it's probably better that you do.
Upvotes: 0