为什么 objc 中,用 self 有时候用.有时候直接空格就好了?

2015-04-29 13:41:01 +08:00
 zhangchioulin
新手上路,问题多多。请见谅。
题目就是问题,感觉好奇怪
2774 次点击
所在节点    iDev
11 条回复
WildCat
2015-04-29 14:17:32 +08:00
. 在 objc 里主要是调用属性(的 getter 方法)
空格(其实我觉得是 [someInstance someMethod])是发送消息(调用方法)
比新手稍微强一点的新手……如有错误请见谅
zooooom
2015-04-29 14:37:14 +08:00
.....卧槽,这个也太新了吧,先把objc的语法看一下吧
snipes
2015-04-29 14:56:30 +08:00
点语法实际上是Objective-C的语法糖,跟用不用self没什么关系。
person p = [[person alloc] init];
p.name = @"xiaoming"; 等价于[p setname:@"xiaoming"];
后一种写法就是oc中纯正的发送消息的写法. 我也是新手,个人理解。
krafttuc
2015-04-29 15:30:15 +08:00
发消息都可以用方括号的啦。

用“.”可以看上去更简洁,而且一定程度上也更符合C访问structure里变量的语法习惯。(当然,还有不少语言的语法也使用点来访问instance variable)所以遇到property,人们就更偏向于用点号。

总之,这很大程度上还是一个编码风格问题。不过如果你们团队其他同学习惯用点号,而你偏偏要用方括号,那样做就显得不太好了。
jesse_luo
2015-04-29 21:06:32 +08:00
vincentxue
2015-04-30 01:33:47 +08:00
首先你说用空格调用是错误的,应该是两边的方括号,不是中间的空格,其实更正确的说法是向对象发送消息而不是调用方法。

答案就是点语法实际上是语法糖,如果你想了解地明白点,可以往下继续看。

其次要弄懂这个问题,你首先要知道为什么可以用点语法调用以及它背后做了什么。

现在写的 Objective-C 代码都是属于 Objective-C 2.0 版本,在 Objective-C 1.0 版本的时候,如果你需要向类外传值,你必须得这么做:



但是这样写 setter 方法会有一个 Bug,那就是如果传入的新变量就是要被赋值的旧变量,那么这个变量就会被释放掉。因为 setter 第一行代码就是 release 旧变量,而旧变量实际上就是新变量。(这个 Bug 只存在于非 ARC 环境下)

所以 setter 变成了现在常见的这样写:



因为需要通过声明方法的方式来让类外部操作类内部的实例变量,那么在使用的时候你得像调用方法一样使用“[]”来操作:



所以如果一个用户模型类有名字、年龄、头像、地址、帐号等等信息要记录的话,那要写非常多这样看起来重复的代码,大概像这样:



方法我就不一一实现了。

Objective-C 2.0 引入了 @property 关键字来声明属性,它的作用是帮你自动声明 setter 和 getter 方法,但不实现。同时提供点语法来访问声明的属性。

所以到目前为止,你省去了很多无趣的 setter/getter 方法的声明,之前的代码就变成了这样:



但是编译器马上就会出现警告,告诉你你只声明 `-name` 和 `setName:` 这两个方法,但是却没有实现它们,你必须使用 @synthesize 或者 @dynamic 或者手动实现它们。

警告信息类似于这样:

property 'name' requires method '-name' to be defined - use @synthesize, @dynamic or provide a method implementation.
property 'name' requires the method 'setName:' to be defined - use @synthesize, @dynamic or provide a method implementation.

通过这个警告就印证的上面的说法,现在你得在这三个方案里选择一个来去掉这个警告,通常会选择第一个使用 @synthesize,此时你的代码就变成了这样:



上面的代码就相当于在 Objective-C 1.0 时的那一堆代码。

因为可以使用点语法访问属性,所以之前的访问代码就变成了这样:



所以实际上使用点语法背后就是在调用 setter/getter 方法,而这一切编译器在编译的时候都会将点语法调用转换为正常的对象消息发送。

另外早在 Xcode 4.3(具体4.几我忘了)就已经不再需要你去显式地写 @synthesize 这行代码了。

同理,无参数的实例方法或者类方法都可以通过点语法调用。
zhangchioulin
2015-05-01 09:34:24 +08:00
@vincentxue 谢谢
zhangchioulin
2015-05-01 09:34:30 +08:00
@jesse_luo 谢谢
zhangchioulin
2015-05-01 09:34:47 +08:00
@krafttuc 谢谢啦
BaiYiChaJi
2015-05-04 10:36:43 +08:00
建议多看看书。。。
zhangchioulin
2015-07-01 19:13:00 +08:00
@vincentxue 谢谢,说的很有道理

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/187221

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX