Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you name your instance/param values?

Being new to Objective-C (but a long term C/++) programmer I'm looking for advice/recommendations on naming conventions for variables.

My personal preference would be to utilize a prefix for instance variables both for clarity within functions and to prevent shadowing of function parameters. However I'm a fan of properties which rules out prefixes (unless you also prefix your property names, which doesn't work too well and looks daft). Similarly I could use the "self.variable" convention, but only if I make EVERYTHING a property.

So given the code below what's your preferred naming style for instance/function variables? And if you don't bother, how do you deal with shadowing on function params?

@interface GridItem : NSObject
{
    CGRect _rect;
    ...  
}
@end

-(void) initFromRect:(CGRect)rect
{
    _rect = rect;
    ...
}

Cheers!

like image 444
Andrew Grant Avatar asked Nov 27 '22 02:11

Andrew Grant


1 Answers

Most Cocoa projects use underbar as a non-IBOutlet instance variable prefix, and use no prefix for IBOutlet instance variables.

The reason I don't use underbars for IBOutlet instance variables is that when a nib file is loaded, if you have a setter method for a connected outlet, that setter will be called. However this mechanism does not use Key-Value Coding, so an IBOutlet whose name is prefixed with an underbar (e.g. _myField) will not be set unless the setter is named exactly like the outlet (e.g. set_myField:), which is non-standard and gross.

Also, be aware that using properties like self.myProp is not the same as accessing instance variables. You are sending a message when you use a property, just like if you used bracket notation like [self myProp]. All properties do is give you a concise syntax for specifying both the getter and setter in a single line, and allow you to synthesize their implementation; they do not actually short-circuit the message dispatch mechanism. If you want to access an instance variable directly but prefix it with self you need to treat self as a pointer, like self->myProp which really is a C-style field access.

Finally, never use Hungarian notation when writing Cocoa code, and shy away from other prefixes like "f" and "m_" — that will mark the code as having been written by someone who doesn't "get it" and will cause it to be viewed by suspicion by other Cocoa developers.

In general, follow the advice in the Coding Guidelines for Cocoa document at the Apple Developer Connection, and other developers will be able to pick up and understand your code, and your code will work well with all of the Cocoa features that use runtime introspection.

Here's what a window controller class might look like, using my conventions:

// EmployeeWindowController.h
#import <AppKit/NSWindowController.h>

@interface EmployeeWindowController : NSWindowController {
@private
    // model object this window is presenting
    Employee *_employee;

    // outlets connected to views in the window
    IBOutlet NSTextField *nameField;
    IBOutlet NSTextField *titleField;
}

- (id)initWithEmployee:(Employee *)employee;

@property(readwrite, retain) Employee *employee;

@end

// EmployeeWindowController.m
#import "EmployeeWindowController.h"

@implementation EmployeeWindowController

@synthesize employee = _employee;

- (id)initWithEmployee:(Employee *)employee {
    if (self = [super initWithWindowNibName:@"Employee"]) {
        _employee = [employee retain];
    }
    return self;
}

- (void)dealloc {
    [_employee release];

    [super dealloc];
}

- (void)windowDidLoad {
    // populates the window's controls, not necessary if using bindings
    [nameField setStringValue:self.employee.name];
    [titleField setStringValue:self.employee.title];
}

@end

You'll see that I'm using the instance variable that references an Employee directly in my -init and -dealloc method, while I'm using the property in other methods. That's generally a good pattern with properties: Only ever touch the underlying instance variable for a property in initializers, in -dealloc, and in the getter and setter for the property.

like image 142
Chris Hanson Avatar answered Jan 11 '23 16:01

Chris Hanson