使用 Objective-C 一年后我对它的看法 已翻译 100%

oschina 投递于 2013/12/15 08:10 (共 15 段, 翻译完成于 12-23)
阅读 19564
收藏 82
2
加载中

我在一年前因需要将RedPhone项目从Android移植到iOS而首次接触Objective-C。大约一个月前我负责的部分(后端:声音,网络,加密部分)已经完成。我们正等着外部的安全审查,同时在内部继续完成UI工作的过程中并未发现任何后端的bug(言外之意开发质量高)。在RedPhone最终发布后,我对于这次工作中哪些做错了,基于android和ios的代码都有哪些不同等等做了讨论。今天想探讨一下去年过程中关于Objective-C的一些体验。

一年前我从未接触过Objective-C.(一行代码也没看过)我是名C#开发。现在我认为自己是名中级Objective-C开发:

虽然还有很多知识上的漏洞但我在现在使用这门语言已算是得心应手。比如,大家都知道不能把nil赋给数组和其他的集合类型,但就在上周我还不知道可以直接插入NSNull来实现。当然了,我只是假设大家只是不会把nils赋给某个集合。(意味着大部分人也不知道这个workaround)

petert
翻译于 2013/12/15 09:16
3

当我讨论语言时,我听起来会倾向于比较挑剔,所以请记住这篇文章不是指控Objective-C无法有效的处理问题。这篇文章是关于我使用Objective-C的经验,它和其他语言不同的地方,以及我遇到的问题。这是我的观点,因为编程领域充满了关于哪种语言更好的完全对立的观点(e.g. 动态 vs 静态类型编程语言),你可以相信,这仅仅是以一对多。一个相关的引用:

仅有两种语言:一种是大家抱怨的,另一种是没人使用的。 —— Bjarne Stroustrup
Ley
Ley
翻译于 2013/12/15 09:10
1

概述

Object-C是C语言的超集,所以很自然的让我注意的第一件事是它哪里和C不同。基本上你在以Obj-C风格写代码时唯一做的类似C的事情(C-ish stuff)是使用头文件和使用前进行类型声明。

奇怪的是,Objective-C使我想起的更多的不是C而是Visual Basic 6。至少,是在我每日使用所遇到的问题上。Obj-C和VB6两者都 喜欢让程序保持 运行下去(即使出错了,译者注)。这是不是个奇怪的现象?程序可能会错过打破当前状态的问题。另外,两种语言使用引用计数来清理内存,这会随着你的深入造成更多内存泄露。永远警惕引入循环引用。最后,两者没有泛型类型。把这些话都直直的装入你的脑子里,否则你接下来的日子会很难过。

BoydWang
翻译于 2013/12/18 18:45
1
还有另一件Obj-C与VB的包袱,例如,在Objective-C中许多对象有 “core foundation”、 “new style” “NeXTSTEP”的形式,而自动引用计数技术早在两年前就已渗透到整个社区了,当然了,还有C的子集。所以,大多数情况下我们可以忽略这些历史包袱,但它们的出现,我并不是暗示说Obj-C与VB是相同的编程语言,它们有很大不同,首先,语法就有很大的不同。
咖啡碼農
翻译于 2013/12/19 10:44
1

语法

Objective-c的语法很特别。传递一个消息(如调用个方法),你需要用方括号把接收消息的对象以及消息括起来。消息由参数名和值组成,因此不能像 list.Insert("test", 0)这样写,而是这样 [mutableArray insertObject:@"test" atIndex:0]。

当调用方法时给每个参数取个名字可以使代码非常清晰,但是不可避免的增加了代码量。总的来说这是件好事。另一方面,我认为让方括号在目标对象之前开着,而不是在目标对象之后(像Java, C#, C++)是个错误。这使你更难确定你在一个表达式的位置,并且使一个简单的序列变成了深层嵌套。扩展一个表达式是个反复的事情,因为你必须回到行首添加 [。 当前输入 ] 时XCode会尝试猜测 [ 的相对位置,但是它老是搞错以致变得更糟。

MrMign
翻译于 2013/12/19 15:29
2

幸运地是,Objective-c有些语法糖可以让你在一般情况下摆脱嵌套。点记法 可以让你重写简单的getter表达式,如[a value] 重写为 a.value。setter, 数组索引,字典查找也有类似的语法糖。他们确实为减少冗长的代码创造了奇迹。

Objective-c 也有容器了,这个是关于这门语言我真的很喜欢的第一件事。你想要个字典?只需要输入@{key:val,key2:val2,...}, 没有自动包装,因此你不得不在每一处添加@符号,像@{@"a":@1,@"b":@2,...}, 但是相比于人们过去不得不做的(大量地NSNumber numberWithInt:,以null结束的NSArray arrayWithObjectsfor:值,another key值,最后不幸中的万幸NSDictionary dictionaryWithObjects:forKeys:)这只是很小的代价。

MrMign
翻译于 2013/12/19 15:49
1

我没有预料到Object-C会有匿名函数的功能,但是它确实有(它们叫做块)。块语法因为缺乏推理类型语法,所以你不得不写^(int x){return x*x;}用来替代 x=>x*x,但是确实足够简明可以被使用。

另外一个对于Object-C语法来说的必要点就是前缀使用“+”和“-”用于区分静态方法和实例方法(错误的...信息)。你将会很快的习惯它,虽然它的这些差别看起来有些滑稽。

奔跑的蛮牛
翻译于 2013/12/17 20:55
1

类型系统

如果让我说一句我恨Objective-C的地方,那一定就是类型系统了。它很难表示出很多有用的类型(例如没有泛型)并且实际上它也不能检查你的工作(甚至在运行时)。虽然它在感觉上很动态,但是我更喜欢静态的强类型。

一开始,Objective-C没有null(但是C语言有,虽然你不常用)。替代的,Objective-C有nil,它很像null除了当你不小心在程序里使用它的时候它不会使程序停止。发给nil的消息不会抛出异常,它仅仅只返回了一个nil并且实际上不作任何的评估。

BoydWang
翻译于 2013/12/18 18:59
1

我是真的真的不喜欢nil. 例如,假设你写了像构造函数的方法,它有一个叫SuperImportantSecurityChecker的参数。
你坚持参数不是nil,因为对不合逻辑的不被执行进行安全检查是很糟糕的。
你也可以写一个测试,故意导致安全失败,并且检查下确实是失败了。你做的很好,因为你忘记了用SuperImportantSecurityChecker参数的值初始化SuperImportantSecurityChecker了。像这样的错误会几年都不会被发现,这多亏了nil。

另一个例子,当程序已经出错了,但是会继续运行,令人吃惊的竟然是缺少运行时类型检查。例如,如果你写NSMutableArray* v = [NSArray array],Objective-C会高兴的将你的可变数组的指针指向一个不可变的数组(你以前甚至没有看到编译报警,因为NSArray.array返回id, 现在它返回 instancetype)。当你尝试去调用给“可变”数组添加对象的方法时,程序会崩溃,错误提示为“selector not found”。这个并不像不可期的nil那样糟糕,nil会悄悄地丢弃要添加的项而不是崩溃,但是查找这些错误是很恼人的。

MrMign
翻译于 2013/12/19 19:42
1
当在块上工作时缺少运行时检查是非常恶心的,因为语言允许你过度自由的指定输入类型。这种写法看起来多么诱人,[array enumerateObjectsUsingBlock:^(NSNumber* obj, NSUInteger index, BOOL *stop) { ... }];,根据你的期望,thatobjshould通常是一个数字而不是generalid,但是有时候你会搞砸它并且不得不追踪问题所在。我已经采取了在大多数块开始前加一行strewingassert([obj isKindOfClass:[WhateverType class]])来先发制人的捕捉这些错误。
BoydWang
翻译于 2013/12/18 19:21
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(28)

gezhonglunta
gezhonglunta
OC的语法确实让人崩溃啊,它比C/C++/Java都要复杂,习惯了Java的语法再来学OC要崩溃了,写代码好累啊
b
bigger
如果没有苹果,这种反人类的语言是不会有任何生存空间的。。。苹果还是那一套,就是要用不一样的规则实现不切实际的大一统
黄海
Object-C垃圾语言,是我见过的最丑陋的语言!
yungsh
yungsh

引用来自“凌晨五点钟”的评论

引用来自“纵使有花兼明月何堪无酒亦无人”的评论

引用来自“看天吃飯”的评论

这篇文章基本上是worthless,其实OBJC是非常好的一种语言,虽然和我们熟悉的很不相同,Xcode是个非常好的写IOS app的工具,不下于visual studio系列,可能差一点,不过差不多接近了,否则不会有那么多app出现。学习Android很快,不过Android相比IOS app开发的效率,感觉要差一些(我想说很多),主要是要想用Android做一个用户体验很好的应用要比iOS难。

好不好不说。大家都觉得ios赚钱。所以学得快,开发的快。wp的更简单。开发工具,编程语言,方便是毋庸置疑的,应用少是为什么。没有利益驱动。

就是这个道理,只要想去做,再难都会简单几分,OC的感觉就是入门快

如果他的语法没那么bt,也许入门会更快
凌晨五点钟

引用来自“纵使有花兼明月何堪无酒亦无人”的评论

引用来自“看天吃飯”的评论

这篇文章基本上是worthless,其实OBJC是非常好的一种语言,虽然和我们熟悉的很不相同,Xcode是个非常好的写IOS app的工具,不下于visual studio系列,可能差一点,不过差不多接近了,否则不会有那么多app出现。学习Android很快,不过Android相比IOS app开发的效率,感觉要差一些(我想说很多),主要是要想用Android做一个用户体验很好的应用要比iOS难。

好不好不说。大家都觉得ios赚钱。所以学得快,开发的快。wp的更简单。开发工具,编程语言,方便是毋庸置疑的,应用少是为什么。没有利益驱动。

就是这个道理,只要想去做,再难都会简单几分,OC的感觉就是入门快
闪电奇迹

引用来自“糖咖啡”的评论

每次看OC的语法,都感到一丝蛋疼。

+1 ,蛋蛋的忧伤。
自由之信
自由之信

引用来自“纵使有花兼明月何堪无酒亦无人”的评论

引用来自“看天吃飯”的评论

这篇文章基本上是worthless,其实OBJC是非常好的一种语言,虽然和我们熟悉的很不相同,Xcode是个非常好的写IOS app的工具,不下于visual studio系列,可能差一点,不过差不多接近了,否则不会有那么多app出现。学习Android很快,不过Android相比IOS app开发的效率,感觉要差一些(我想说很多),主要是要想用Android做一个用户体验很好的应用要比iOS难。

好不好不说。大家都觉得ios赚钱。所以学得快,开发的快。wp的更简单。开发工具,编程语言,方便是毋庸置疑的,应用少是为什么。没有利益驱动。

是的,主要是因为apple的手机销量,不是工具问题。谢谢提点。
曾宪华-
曾宪华-
OC 有这么个风格
NSArray *currenArray = [[NSArray alloc] init];
比较少用 JAVA风格如下: NSArray *currenArray = [NSArray array]; 一般不采取类方法来初始化,不过还的看需求
zoujiaqing
zoujiaqing
OC语法真是.....无法让人接受!
xmlspyspring
xmlspyspring
呵呵,用过一段时间objc,不是一般的恶心,有着最bt的语法,冗长的表达式.
还有工程相关的配置项也多如牛毛.
返回顶部
顶部