6

I run into a fairly common scenario in Objective-C where I pass in a variable to an init method and then want to assign it to an instance variable of the same name. However I have not found a way to scope the variables to clarify which is the value from the message argument and which is the instance variable.

Say I have some class such as the following:

@interface MyObject
{
    NSString *value;
}
- (id)initWithValue:(NSString *)value;
@end

In my implementation I want my init method to look something like this:

- (id)initWithValue:(NSString *)value
{
    self = [super init];
    if(self) {
        self.value = value;  // This will not work with instance variables
    }
}

I know of three solutions:

  1. Create a property, which allows calling self.value
  2. Rename my instance variable, such as _value
  3. Rename my init argument variable, such as initValue or argValue

I am not pleased with any of these solutions. Adding a property either makes the property publicly available on the interface or, if I use an extension, hides it from inheritors. I also do not like having different names for the variables or using an underscore, which perhaps comes from developing in other languages such as Java and C#.

Is there a way to disambiguate instance variables from message arguments? If not, is there a coding guideline in Cocoa for how to solve this problem? I like following style guidelines when appropriate.

Update

After thinking about how to do this in C, I came up with the solution of self->value. This works, but it produces a compiler warning that the Local declaration of 'value' hides instance variable. So this is not a satisfactory solution either since I have a zero-warning goal.

David V
  • 11,531
  • 5
  • 42
  • 66

3 Answers3

4

For setters (and by extension initializers), I believe the convention is to prefix the parameter name with new:

- (void)setCrunk:(Crunk *)newCrunk;
- (id)initWithCrunk:(Crunk *)newCrunk;

In general, I think the most common form I've seen is to call the parameter theCrunk, but Apple seems to recommend aCrunk.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • I use `crunkIn` because otherwise you don't get autocomplete. – Dan Rosenstark Jan 05 '12 at 18:27
  • @Josh Caswell, for consistency is the convention to use whichever prefix you choose (new, the, a) in all cases - even if you do not assign it? Perhaps it is simply passed into another message, such as to `[super setCrunk:]` – David V Jan 05 '12 at 19:39
  • @DavidV: I'd say leave the prefix off unless it's necessary to disambiguate with an ivar, but I can't pretend that's anything other than my preference. – jscs Jan 07 '12 at 01:56
  • I like `aCrunk` because it's only one additional character to type. – Roland May 22 '17 at 06:12
3

And changing the name to "inValue" is not a good idea? What you have here - your 'solution' is complex, especially with the accessors, etc of Obj-C 2. Since self.value and inValue are different things, they need different names.

Note that you can use

-(void)method1:(NSString*)value; 

in the header

and

-(void)method1:(NSString*)inValue; 

in the .m file.

Tom Andersen
  • 7,132
  • 3
  • 38
  • 55
  • I have noticed that you can have different argument names in the interface and implementation. My goal is to have consistency so that developers don't have to think about what name is used. Have you used the convention of different names in the interface and implementation? How has it worked out for your team? – David V Jan 05 '12 at 19:23
  • @DavidV this is a problem that is not relevant to the interface, only to the implementation. Tom's point is 100% valid. – Dan Rosenstark Jan 05 '12 at 19:38
  • @Yar, I don't mean to say that Tom's point is not valid. I understand that the interface will remain consistent and a developer working in the class will have a consistent naming scheme for ivars. It is simply that this is a solution I initially did not consider until I read Tom's post and now I am considering it. I do value consistency in interfaces higher than consistency in implementation, but I still like to have the latter. – David V Jan 05 '12 at 19:58
  • @DavidV understood. That said, if methods are short (as they should be), you can see the convention that the dev chose for the paramIn name. Intefaces, on the other hand, should be perfectly consistent – Dan Rosenstark Jan 05 '12 at 20:17
2

If you use only 1 the compiler will give you a warning.

You can combine 1 & 2 by using :

@synthesize value = _value;

If you want to hide your variable from the inheritors you can declare a empty named category and declare your property there.

For 3 you can use aValue for your argument.

Stefan Ticu
  • 2,093
  • 1
  • 12
  • 21
  • 1
    Somewhere (can't remember) it's written that you are not supposed to use `_` as a prefix. Only Apple does that. You should use it as a suffix, which Google recommends somewhere (which I also can't remember). So `value = value_`... check out http://www.kevincallahan.org/software/accessorizer.html and also AppCode if you are serious about using this solution. – Dan Rosenstark Jan 05 '12 at 18:28
  • I don't agree, it's only a style convention. – Stefan Ticu Jan 05 '12 at 18:30
  • You don't agree that Apple recommends against using the underscore as a prefix? – Dan Rosenstark Jan 05 '12 at 18:36
  • I don't agree with your comment : Apple doesn't recommend that. – Stefan Ticu Jan 05 '12 at 18:39
  • If this is a proof for you, then leave it like this. – Stefan Ticu Jan 05 '12 at 18:48
  • 2
    Yup it's recommended to not prefix method names with underscores. The `_` for variables is just a matter of style. If I `@synthesize myVar = _myVar;` and I override a method xcode will auto complete to `- (void)setMyVar:(id)myVar;`. If there is a naming collision with another programmers ivar I will soon get a warning. The main thing is being consistant on a per project basis. If I work on someone else's project I will adapt to use what they have used to keep consistency. – Paul.s Jan 05 '12 at 18:49
  • I was talking about variables so I agree with you. – Stefan Ticu Jan 05 '12 at 18:53
  • Thanks, I agree with the style consistency, we do the same thing. – Stefan Ticu Jan 05 '12 at 19:08
  • @Paul.s I was actually agreeing with his/her point too :) It seems it's not a problem as a prefix for iVar names. – Dan Rosenstark Jan 05 '12 at 19:08