@synthesize window=_window;

 

Modern runtime

In Objective-C 2.0 you declare variables like this:

@interface User : NSObject 
@property (nonatomic, assign) NSInteger age; 
@end 
@implementation User { 
@synthesize age; 
@end 

which is translated by the compiler as follows:

@interface User : NSObject { 
    NSInteger age; 
} 
@end 
@implementation User 
-(void)setAge:(NSInteger)newAge { 
    age=newAge; 
} 
-(void)age { 
    return age; 
} 
@end 

If you prefer to use the underscore convention just add the following:

@synthesize age=_age; 

That's all you need because with the modern runtime, if you do not provide an instance variable, the compiler adds one for you. Here is the code that gets compiled:

@interface User : NSObject { 
    NSInteger _age; 
} 
@end 
@implementation User 
-(void)setAge:(NSInteger)newAge { 
    _age=newAge; 
} 
-(void)age { 
    return _age; 
} 
@end 

What happens if you add both the ivar and the @property? If the variable has the same name and type, the compiler uses it instead generating a new variable. Quoting The Objective-C Programming Language > Declared Properties > Property Implementation Directives:

There are differences in the behavior of accessor synthesis that depend on the runtime:

  • For the modern runtimes, instance variables are synthesized as needed. If an instance variable of the same name already exists, it is used.

  • For the legacy runtimes, instance variables must already be declared in the @interface block of the current class. If an instance variable of the same name as the property exists, and if its type is compatible with the property’s type, it is used —otherwise, you get a compiler error.

The only benefit of declaring both an ivar and the @property is that the ivar acquires protected access (it is only accessible from the current class and its subclasses).

Legacy runtime

But if you need to support the legacy runtime you must either provide an instance variable with the same name and compatible type of the property or specify another existing instance variable in the @synthesize statement.

So the legacy code without underscores would be:

@interface User : NSObject { 
    NSInteger age; 
} 
@property (nonatomic, assign) NSInteger age; 
@end 
@implementation User 
@synthesize age; 
@end 

Or if you prefer the underscore convention:

@interface User : NSObject { 
    NSInteger _age; 
} 
@property (nonatomic, assign) NSInteger age; 
@end 
@implementation User 
@synthesize age = _age; 
@end 

What is the best way?

The written conventions tells you to use the Objective-C 2.0 way whenever you can, and avoid underscores.

Coding Guidelines for Cocoa: Typographic Conventions:

Avoid the use of the underscore character as a prefix meaning private, especially in methods. Apple reserves the use of this convention. Use by third parties could result in name-space collisions; they might unwittingly override an existing private method with one of their own, with disastrous consequences.

However, Apple still uses the underscore way in their templates. Why? I don't know. It's common to see ivars with leading underscores (or that's my experience at least).

ISO/IEC 9899 7.1.3 Reserved identifiers (aka C99):

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
  • All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

On top of that, double leading underscore is traditionally reserved for the vendor of the preprocessor / compiler / library. This avoids the case where you use __block somewhere in your code, and Apple introduces that as a new non-standard keyword.

Google Objective-C Style guide:

Variable Names Variables names start with a lowercase and use mixed case to delimit words. Class member variables have trailing underscores. For example: myLocalVariable, myInstanceVariable_. Members used for KVO/KVC bindings may begin with a leading underscore iff use of Objective-C 2.0's @property isn't allowed.

I sympathize with Google, they follow the standard but they still use a convention, and it's one that doesn't force you to type one more character before XCode fires the autocomplete.

Leading underscore is also discouraged in C++ (see What are the rules about using an underscore in a C++ identifier?) and Core Data properties (try adding a leading underscore in the model and you'll get "Name must begin with a letter").

Trailing underscore seems the sensible choice, but if you like something else, collisions are unlikely to happen, and if they do, you'll get a warning from the compiler. I'm used to _var, but that's just me.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值