Objective-C与C#相比如何?
我最近购买了一台Mac,主要用于VMWare Fusion下的C#开发。 随着所有漂亮的Mac应用程序,我已经开始考虑Xcode潜伏只是一个安装点击,并学习Objective-C。
这两种语言之间的语法看起来很不一样,大概是因为Objective-C起源于C,而C#起源于Java / C ++。 但是可以学习不同的语法,所以应该是OK的。
我主要关心的是使用这种语言,如果它能帮助产生结构良好,可读性和优雅的代码。 我非常喜欢C#中的LINQ和var之类的特性,并想知道Objective-C中是否有等价的或更好的/不同的特性。
我想用Objective-C开发什么样的语言function? 我将获得哪些function?
编辑:框架比较是有用的和有趣的,但语言比较是什么这个问题真正要求(部分我的错误原来标记与.net
)。 据推测,Cocoa和.NET都是非常丰富的框架,两者都有自己的目的,一个针对Mac OS X和其他Windows。
感谢您迄今为止的经过深思熟虑和合理平衡的观点!
没有语言是完美的所有任务,Objective-C也不例外,但有一些非常具体的细微之处。 就像使用LINQ
和var
(我不知道直接replace),其中一些是严格的语言相关的,而另外一些是与框架相关的。
( 注意:正如C#与.NET紧密结合,Objective-C与Cocoa紧密结合,因此,我的一些观点可能与Objective-C无关,但没有Cocoa的Objective-C类似于没有.NET / WPF / LINQ,在Mono下运行等等。这不是通常的做法。)
我不会假装完全阐述差异,优点和缺点,但是这里有一些想到的东西。
-
Objective-C最好的部分之一是dynamic本质 – 而不是调用方法,你发送消息,运行时dynamic路由。 与dynamic打字相结合(明智地),这可以使许多强大的模式变得更简单甚至微不足道。
-
作为C的一个超集,Objective-C相信你知道你在做什么。 与C#和Java等语言的托pipe和/或types安全方法不同,Objective-C可以让你做你想做的事,并体验其后果。 显然,这有时是危险的,但事实上语言并没有阻止你做大部分事情,这是相当强大的。 ( 编辑:我应该澄清,C#也有“不安全”的function,但他们的默认行为是托pipe代码,你必须明确select退出。相比之下,Java 只允许types安全的代码,并从不暴露原始指针C和其他人的做法。)
-
类别(在没有子类或有权访问源的类上添加/修改方法)是一把双刃剑。 它可以极大地简化inheritance层次并消除代码,但是如果你做了一些奇怪的事情,结果有时会令人困惑。
-
cocoa在许多方面使创buildGUI应用程序变得更加简单,但是你必须围绕这个范例来打包。 MVCdevise在Cocoa中是普遍的,代表,通知和multithreadingGUI应用程序等模式非常适合于Objective-C。
-
cocoa绑定和键值观察可以消除大量的胶水代码,而Cocoa框架则充分利用了这一点。 Objective-C的dynamic调度与此息息相关,只要符合键值,对象的types就无关紧要。
-
你可能会错过generics和命名空间,他们有它们的好处,但是在Objective-C的思想和范式中,它们将是精细而不是必需品。 (generics是关于types安全性和避免投射的,但是在Objective-C中的dynamicinput使得这在本质上是不成问题的。如果做得好,命名空间将是很好的,但是它足够简单以避免成本可以超过收益的冲突对于遗留代码。)
-
为了实现并发性,Blocks(Snow Leopard中的一种新语言function,并在许多Cocoa API中实现)非常有用。 几行(经常与Grand Central Dispatch(在10.6上是libsystem的一部分)一起使用)可以消除重要的callback函数,上下文等等的模板(块也可以在C和C ++中使用,当然也可以添加到C# )NSOperationQueue也是一个非常方便的方法,通过调度自定义的NSOperation子类或GCD自动在一个或多个不同的线程上执行的匿名块为您自己的代码添加并发。
我已经用C,C ++和C#编程了20多年,最早是在1990年开始的。我刚刚决定看看iPhone开发,Xcode和Objective-C。 哦,我的天啊……所有关于微软的抱怨我都收回了,现在我意识到代码已经是多么糟糕了。 与C#相比,Objective-C过于复杂。 我已经被C#宠坏了,现在我明白了微软所做的所有努力。只是用方法调用来阅读Objective-C是很难读懂的。 C#在这方面很优雅。 这只是我的看法,我希望苹果的开发语言和苹果的产品一样好,但亲爱的我,他们有很多东西要向微软学习。 毫无疑问,C#.NET应用程序可以比XCode Objective-C更快地运行应用程序。 苹果公司当然应该从微软的书中脱颖而出,然后我们将拥有完美的环境。 🙂
这里没有技术评论,但是我发现Objective-C的可读性差得多。 鉴于Cinder6给出的例子:
C#
List<string> strings = new List<string>(); strings.Add("xyzzy"); // takes only strings strings.Add(15); // compiler error string x = strings[0]; // guaranteed to be a string strings.RemoveAt(0); // or non-existant (yielding an exception)
Objective-C的
NSMutableArray *strings = [NSMutableArray array]; [strings addObject:@"xyzzy"]; [strings addObject:@15]; NSString *x = strings[0]; [strings removeObjectAtIndex:0];
它看起来很糟糕。 我甚至试着在上面读2本书,他们很早就把我弄丢了,通常我不会用编程书籍或者语言来获取它。
我很高兴我们有Mac OS的Mono,因为如果我不得不依靠苹果来给我一个良好的开发环境…
手动内存pipe理是Objective-C似乎最有问题的初学者,主要是因为他们认为它比它更复杂。
Objective-C和Cocoa的推广依赖于执法方面的惯例; 知道并遵循一小部分规则,并且通过dynamic运行时间获得很多免费的回报。
不是100%真实的规则,但是对于日常而言足够好的是:
- 每一次调用
alloc
都应该和当前作用域末尾的release
相匹配。 - 如果你的方法的返回值已经通过
alloc
获得,那么它应该返回return [value autorelease];
而不是被一个release
匹配。 - 使用属性,没有规则三。
下面再解释一下。
内存pipe理是基于所有权的; 只有对象实例的所有者才能释放对象,其他人都应该什么都不做。 这意味着95%的代码将Objective-C视为垃圾收集。
那么其他5%呢? 您有三种方法可以查找,从这些方法接收到的任何对象实例都由当前的方法范围拥有:
-
alloc
- 任何以new开头的方法,如
new
或newService
。 - 任何包含单词拷贝的方法,比如
copy
和mutableCopy
。
该方法有三种可能的select,在退出之前如何处理拥有的对象实例:
- 如果不再需要,则
release
它。 - 通过简单地分配一个字段(实例variables)或全局variables来赋予其所有权。
- 放弃所有权,但让别人有机会在实例消失之前通过调用
autorelease
来获得所有权。
那么你应该什么时候主动retain
所有权呢? 两种情况:
- 在初始化程序中分配字段时。
- 手动执行setter方法时。
当然,如果你在生活中看到的所有东西都是Objective C,那么它的语法看起来是唯一可能的。 我们可以称你为“编程处女”。
但是由于大量的代码是用C,C ++,Java,JavaScript,Pascal和其他语言编写的,所以你会发现ObjectiveC与所有这些都不一样,但是却不是一个好的方法。 他们有这个理由吗? 让我们来看看其他stream行的语言:
C ++为C增加了很多额外的function,但它只是根据需要改变了原来的语法。
与C ++相比,C#增加了很多额外function,但是它只是改变了C ++中难看的东西(例如从界面中删除“::”)。
Java改变了很多东西,但除了需要改变的地方外,它保持了熟悉的语法。
JavaScript是一个完全dynamic的语言,可以做很多东西ObjectiveC不能。 尽pipe如此,它的创造者并没有发明一种调用方法和传递参数的新方法,以便与世界其他地方不同。
就像ObjectiveC一样,Visual Basic可以按顺序传递参数。 你可以命名这些参数,但是你也可以按照常规方式传递它们。 无论你使用什么,都是用逗号分隔的方式,每个人都能理解。 逗号是通常的分隔符,不仅在编程语言中,而且在书籍,报纸和书面语言中。
Object Pascal与C有不同的语法,但是它的语法实际上更容易被程序员读取(可能不是计算机,但是谁在乎计算机是怎么想的)。 所以也许他们离题了,但至less他们的结果是更好的。
Python有不同的语法,比Pascal更容易阅读(对于人类)。 所以当他们改变它,使其不同,至less他们为我们的程序员更好。
然后我们有ObjectiveC。 为C增加了一些改进,但发明了自己的接口语法,方法调用,parameter passing以及不是什么。 我想知道他们为什么不交换+和 – 以便减去两个数字。 它本来会更酷。
史蒂夫乔布斯支持ObjectiveC搞砸了。 当然,他不能支持C#,这是更好的,但属于他最糟糕的竞争对手。 所以这是一个政治决定,而不是一个实际的决定。 技术决策是出于政治原因而制定的,技术总会受到影响。 他应该领导公司,他做得很好,把编程事务留给真正的专家。
如果他决定用ObjectiveC以外的其他语言编写iOS和支持库,我肯定会有更多的iPhone应用程序。 对于除铁器粉丝,处女程序员和史蒂夫·乔布斯(Steve Jobs)之外的所有人来说,ObjectiveC都显得荒谬,丑陋和令人厌恶。
有一件事我喜欢objective-c,对象系统是基于消息的,它可以让你做非常好的事情,你不能在C#中做(至less不支持dynamic关键字!)。
另一个关于编写cocoa应用程序的好处是Interface Builder,它比Visual Studio中的表单devise器好得多。
关于obj-c的事情(作为一个C#开发人员)让我烦恼,因为你必须pipe理你自己的内存(有垃圾回收,但在iPhone上不起作用),而且它可能非常冗长,因为select器语法和所有的[]。
作为一名刚刚从C#4.0开始使用Objective-C for iPhone的程序员,我缺lesslambdaexpression式,特别是Linq-to-XML。 lambdaexpression式是特定于C#的,而Linq-to-XML实际上更多的是.NET和Cocoa的对比。 在我写的示例应用程序中,我在string中有一些XML。 我想把这个XML的元素parsing成一个对象的集合。
要在Objective-C / Cocoa中完成这个,我必须使用NSXmlParser类 。 这个类依赖于另一个实现了NSXMLParserDelegate协议的对象,当读取一个元素的开放标签,读取一些数据(通常在元素内),以及读取某个元素的结束标签时,调用的方法被调用(读取:发送的消息) 。 你必须跟踪parsing状态和状态。 而且我真的不知道如果XML无效会发生什么。 深入细节和优化性能是非常好的,但是哦,那是一大堆代码。
相比之下,下面是C#中的代码:
using System.Linq.Xml; XDocument doc = XDocument.Load(xmlString); IEnumerable<MyCustomObject> objects = doc.Descendants().Select( d => new MyCustomObject{ Name = d.Value});
就是这样,你有一组从XML获取的自定义对象。 如果你想过滤这些元素的价值,或只是那些包含一个特定的属性,或者如果你只是想要第一个5,或跳过第一个1,并得到下一个3,或只是找出是否有任何元素返回BAM,就在同一行代码中。
在Objective-C中有许多开源类使得这个处理变得更加容易,所以很多繁重的工作。 这不是内置的。
*注意:我没有实际编译上面的代码,只是作为一个例子来说明C#所要求的相对缺乏冗长性。
内存pipe理可能是最重要的区别。 随着C#你得到垃圾回收,凭借它是一个基于CLR的语言。 有了Objective-C,你需要自己pipe理内存。
如果你来自C#背景(或者任何现代语言),那么转换到没有自动内存pipe理的语言将是非常痛苦的,因为你将花费大量的编码时间来正确地pipe理内存(和debugging好)。
这是一个比较两种语言的不错的文章: http : //www.coderetard.com/2008/03/16/c-vs-objective-c/
除了两种语言之间的范式差异之外,没有太大的区别。 尽pipe我讨厌这么说,但是你可以像使用Objective-C和Cocoa一样对.NET和C#做类似的事情(可能不那么容易)。 从Leopard开始,Objective-C 2.0就有了垃圾回收function,所以你不必自己pipe理内存,除非你想(与旧的Mac和iPhone应用程序的代码兼容性有两个理由)。
就结构化的可读代码而言,程序员和其他任何语言一样,都有很大的负担。 然而,我发现消息传递范式很适合于可读代码,只要你适当的命名你的函数/方法(就像其他语言一样)。
我会第一个承认我对C#或.NET不是很熟悉。 但奎因上面列举的原因是我不在乎的几个原因。
在obj-c中使用的方法调用可以轻松读取代码,在我看来,它比c#更优雅,obj-c构build于c之上,因此所有的c代码都可以在obj-c中正常工作。 对我来说,大卖家是obj-c是一个开放的标准,所以你可以find任何系统的编译器。