V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
zhangchioulin
V2EX  ›  iDev

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

  •  
  •   zhangchioulin · 2015-04-29 13:41:01 +08:00 · 2596 次点击
    这是一个创建于 3293 天前的主题,其中的信息可能已经有所发展或是发生改变。
    新手上路,问题多多。请见谅。
    题目就是问题,感觉好奇怪
    11 条回复    2015-07-01 19:13:00 +08:00
    WildCat
        1
    WildCat  
       2015-04-29 14:17:32 +08:00 via iPhone
    . 在 objc 里主要是调用属性(的 getter 方法)
    空格(其实我觉得是 [someInstance someMethod])是发送消息(调用方法)
    比新手稍微强一点的新手……如有错误请见谅
    zooooom
        2
    zooooom  
       2015-04-29 14:37:14 +08:00
    .....卧槽,这个也太新了吧,先把objc的语法看一下吧
    snipes
        3
    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
        4
    krafttuc  
       2015-04-29 15:30:15 +08:00   ❤️ 1
    发消息都可以用方括号的啦。

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

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

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

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

    现在写的 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
        7
    zhangchioulin  
    OP
       2015-05-01 09:34:24 +08:00
    @vincentxue 谢谢
    zhangchioulin
        8
    zhangchioulin  
    OP
       2015-05-01 09:34:30 +08:00
    @jesse_luo 谢谢
    zhangchioulin
        9
    zhangchioulin  
    OP
       2015-05-01 09:34:47 +08:00
    @krafttuc 谢谢啦
    BaiYiChaJi
        10
    BaiYiChaJi  
       2015-05-04 10:36:43 +08:00
    建议多看看书。。。
    zhangchioulin
        11
    zhangchioulin  
    OP
       2015-07-01 19:13:00 +08:00
    @vincentxue 谢谢,说的很有道理
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1655 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 16:18 · PVG 00:18 · LAX 09:18 · JFK 12:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.