ios下划线变量:为什么变量前要加下划线才有用?

时间:2022-01-14 19:45:25

先看一段代码。

 

复制代码

  1. appdelegate.h
  2. @property (weak) IBOutlet NSMatrix *StockType;
  3. @property (weak) IBOutlet NSMatrix *market;
  4. appdelegate.m
  5. NSCell *st=[market selectedCell];

编译时,总是提示,找不到market变量,但是StockType却没问题。 
如果根据系统建议,在market前加上下划线,变成_market却可以正常编译和执行。 
 
但是到底是为什么呢? 
 
经过对比我发现,在m文件中还有这么一段。

 

复制代码

  1. appdelegate.m
  2. @synthesize StockType;

差异就在这里,只有在synthesize后面加上market,就不用再用下划线了。 
虽然原因还是不清楚,但是至少问题解决了。

A:

Xcode的编译期自动补全造成的 
 
在.m实现文件中,如果使用property,必须使用 self.property 的方式调用 getter 方法,而如果想要直接实例变量,必须在 m  文件中通过 synthesize 关键字同步过来 
 
所以在早期的 xcode 中(我记得应该是4之前),在.m文件中,必须手写 @synthesize 属性名 = 实例变量名 的方式,将所有属性同步 
而按照oc 的官方命名约定,为了避免变量泄漏,实例变量名一般都建议使用下划线前缀表示法,也就是如果property名称叫 abc,对应的实例变量名就定义为 _abc 
因此在.m代码中所有的property都需要手动按照 @synthesize property = _property 的方式与实例变量同步 
 
这样的写法是如此普遍,以至于xcode4 之后,编辑器添加了自动同步补全功能,只需要在 h 文件中定义 property,在编译期m文件会自动补全出 @synthesize property = _property 的代码,不再需要手写,避免了“体力代码”的手动编码 
 
但是这样要求实例变量名一定等于 "_"+属性名又不太灵活, 如果开发人员需要指定不同的属性名,就需要在 .m 文件中手动编写 @synthesize 了 
 
你的例子中, 
 
如果m中什么都不写 
xcode会默认在编译期为 market 属性,补全成 @synthesize market = _market,实例变量名为 _market 
 
如果m中指定了 @synthesize market 
xcode会认为你手动指定了实例变量名为 market ,编译期补全成:@synthesize market = market,实例变量名为 market 
 
 
很容易验证,你在m中定义为 @synthesize market = _xyz,你在.m文件中使用的实例变量名就是 _xyz 了