学习Objective-C时遇到的奇妙事件(一)

最近为了以后恰饭的事情,学起了Objective-C。

可能是我水平不够吧,我到现在都还没办法理解Objective-C中很多地方的设计,甚至对我来说它就是一坨屎(x

下面是几个我没办法理解的地方。

一、用中缀表达式作为方法名。

这的确很有趣,但是也很繁琐。

- (void) setObject:(Something *)sth atIndex:(unsigned long)index addSuffix:(NSString *)suffix;

↑定义一个有三个参数的方法就要写这么长,爽吗

而且参数名本身也是函数名的组成部分。也就是说,在调用的时候要把参数的每一个名字都给写出来,就像这样:

[obj setObject:obj atIndex:index addSuffix:@"我佛了"]

如果写惯了C++,Java这种语言的话,写成这种形式可能会比较好理解:

obj.setObject(obj, index, "我佛了")

没错,在Objective-C中,你要把所有的参数名都给填完整了,因为这就是方法名的一部分,你不写完整人家不认这个方法。

在Python中你可以把参数名写完整,也可以只指定一些参数,我觉得这是很聪明的做法。

而且在Objective-C中提倡的代码风格里,越长越详细的方法名是越好的……不说了,我真的希望我的丁日能有ObjC的函数名那么长。

二、用中括号调用方法

为!什!么!方法调用要用中括号?!

obj.doSomething() 明显写起来比 [obj doSomething] 方便多啊?!多次调用的时候就更蛋疼了,obj.alloc().init()和 [[obj alloc] init] ,一个是链式,一个是嵌套,那写起来明显是链式更方便也更好理解啊?!

我到现在都很难想象,如果多几层调用的话,这个方法调用会变成什么样子。

[obj doSomething:[[dog poo] melt] byPerson:[Villager hair:[Color blue] eyes:[EyeSize big]] ]

↑不知道实际开发的代码会不会出现这种情况

三、在使用中括号调用的前提下又引入点表达式

Objective-C是面向对象的语言,既然是对象,那也逃不过 getter 和 setter 函数的设置。Objective-C弄了一个非常匪夷所思的语法糖,不过在介绍之前我想说说我昨天遇到的事。

我定义了一个类,里面有一个setter叫setColor:

- (void)setColor:(int)color {
    self.color = color;
}

因为类内的成员也叫color,setter的参数也叫color,所以参数名字会覆盖掉类内的成员color。

我本以为这个 self 实际上和 C++ 中的 this 是一样的,都是指向调用本方法的对象。

但我错了。这是个语法糖。我先放上这么写的最终结果吧。

锵锵!爆栈了!

是的没错,这个语法糖的效果就是调用setter。

self.color = xxx 和 [self setColor:xxx] 是等价的,所以如果在setter中这么写会引起一个无限递归,然后爆栈。

后来我看了书才知道,这个语法糖叫点表达式,如果作为左值就会调用 setter ,如果作为右值就会调用 getter 。总之 obj.color 这个东西不是单纯的获取变量,而是调用对象的 setter 或者 getter 函数。

我佛了,真有你的啊,Objective-C!

作者: 梁小顺

脑子不太好用的普通人。 顺带一提性格也有点古怪。 在老妈子和厌世肥宅中来回切换。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据