最近为了以后恰饭的事情,学起了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!