Objective-C与C#相比如何?[关闭]


87

我最近购买了Mac,并将其主要用于VMWare Fusion下的C#开发。有了周围所有不错的Mac应用程序,我开始考虑仅需单击安装即可隐藏Xcode,并学习Objective-C。

两种语言之间的语法看起来非常不同,大概是因为Objective-C起源于C,C#起源于Java / C ++。但是可以学习不同的语法,因此应该可以。

我主要关心的是使用该语言,它是否有助于生成结构良好,可读性强的代码。我真的很喜欢C#中的LINQ和var之类的功能,并且想知道Objective-C中是否有等效或更好/不同的功能。

使用Objective-C开发时会错过哪些语言功能?我将获得什么功能?

编辑:框架比较非常有用且有趣,但是语言比较才是这个问题真正要问的(部分原因是我最初使用标记的错误.net)。大概Cocoa和.NET本身都是非常丰富的框架,并且都有其用途,一个针对Mac OS X,另一个针对Windows。

谢谢您到目前为止的深思熟虑和合理平衡的观点!


27
Xcode并不完美,但是它确实具有许多强大而有用的功能。不将某些东西视为“纯粹的邪恶”而不进行备份或提供任何上下文进行比较的说法是FUD并不能帮助任何人。无论如何,这与问题无关。
奎因·泰勒

11
Xcode 3.2可能是我使用过的最好的IDE,它具有优雅的断点处理,静态分析,内联错误消息和大量其他功能。顺便说一句,它是“ Xcode”而不是“ XCode”。@Nathan,我真的不明白为什么在有关语言的讨论中,没有任何理由就需要通过称其为“纯粹的邪恶”来贬低Xcode。
PlagueHammer

6
使用Objective-C将获得的一大好处是您将可以访问Cocoa框架。而且,C,C#,Java和C ++都具有相同的语法传统。Objective-C从Smalltalk获得其语法。
Amok,2009年

4
您使用VMWare融合进行C#工作吗?只需使用mono和monodevelop(这是适用于Mac和Linux的.NET和Visual Studio的开源版本。使用Mono,您还可以使用C#创建Mac和iPhone应用程序,同时还使用.NET库和Cocoa …
罗宾·黑格隆德·汉森

5
@ user668039 15年使用C#的经验?它于2001年发布!
伊恩·纽森

Answers:


89

没有一种语言能完美地完成所有任务,Objective-C也不例外,但是有一些非常具体的优点。就像使用LINQvar(我不知道直接替换)一样,其中一些严格与语言相关,而其他则与框架相关。

注意:正如C#与.NET紧密耦合,Objective-C与Cocoa紧密耦合。因此,我的一些观点似乎与Objective-C无关,但是没有Cocoa的Objective-C类似于没有.NET / WPF / LINQ,在Mono下运行,等等。这不是通常的工作方式。)

我不会假装对差异,优点和缺点进行详尽的阐述,但是这里有一些值得我们注意的地方。

  • Objective-C最好的部分之一是动态性质-您发送消息而不是调用方法,运行时动态路由消息。(明智地)将其与动态类型结合使用,可以使许多强大的模式更易于实现,甚至变得微不足道。

  • 作为C的严格超集,Objective-C相信您知道自己在做什么。与C#和Java之类的语言的托管和/或类型安全方法不同,Objective-C可让您做自己想做的事情并体验后果。显然,这有时可能很危险,但是这种语言并不能有效地阻止您执行大多数操作,这一事实非常有力。(编辑:我应该澄清C#也具有“不安全”的特性和功能,但是它们的默认行为是托管代码,您必须显式选择退出。相比之下,Java 允许类型安全代码,而从不公开原始指针。 C和其他人所做的方式。)

  • 类别(在类中添加/修改方法而无需子类化或无法访问源代码)是一把很棒的双刃剑。它可以极大地简化继承层次结构并消除代码,但是如果您做一些奇怪的事情,结果有时会令人困惑。

  • Cocoa在许多方面使创建GUI应用程序变得更加简单,但是您必须将头放在范式上。MVC设计在Cocoa中无处不在,并且诸如委托,通知和多线程GUI应用之类的模式非常适合Objective-C。

  • 可可绑定和键值观察可以消除大量胶水代码,可可框架广泛利用了这一点。Objective-C的动态调度与此协同工作,因此只要符合键值,对象的类型就无关紧要。

  • 您可能会错过泛型和名称空间,它们有其好处,但是在Objective-C的思维方式和范例中,它们将是美好的事物,而不是必需品。(泛型都是关于类型安全和避免强制转换的,但是Objective-C中的动态类型本质上是不成问题的。如果做得好,命名空间会很好,但是要避免冲突就足够简单了,可以说成本超过了收益,尤其是用于旧代码。)

  • 对于并发而言,Blocks(Snow Leopard中的一项新语言功能,已在数十种Cocoa API中实现)非常有用。几行代码(通常与Grand Central Dispatch结合使用,后者是10.6的libsystem的一部分)可以消除回调函数,上下文等的大量重复。(块也可以在C和C ++中使用,并且可以肯定地添加到C#中, NSOperationQueue也是一种非常方便的方法,可通过分派自定义的NSOperation子类或匿名块(将GCD自动在您的一个或多个不同线程上执行)来向您自己的代码添加并发性。


7
从技术上讲,C#具有ObjC具备的所有非类型安全的电源功能:原始指针,指针算术,绑定未经检查的数组,联合,alloca。它只是不能使它们易于访问-您需要明确选择加入。
帕维尔·米纳夫

8
我之所以简单提及Cocoa是因为,Objective-C中编程的大部分吸引力在于Cocoa框架。如果没有.NET和/或WPF,C#是否会很有趣?询问者特别提到LINQ,因此他显然是在寻求语言之外的经验。
奎因·泰勒

7
没关系 我不是想和C#打架。如果我必须编写Windows软件,那就是我要使用的软件。我只是想指出这些语言与相关工具之间的异同。显然,您对C#更有经验,而我对Objective-C更有经验。我很感谢您的澄清,但更具建设性的回答和减少头发的分裂可能最有用。
奎因·泰勒

11
这不是头发分裂,奎因。我只是指出,从语言比较开始,就变成了对您的答复中的某些时候可可的优劣的一般性讨论。我仍然要指出,您对Cocoa的观点不是比较 -他们说“ X做得很好”-也许是这样-但他们没有说“它比C#做得更好/更糟” WPF”,这就是问题的大致范围。
帕维尔·米纳夫

6
+1最佳答案奎因
h4xxr

54

我从1990年开始从事C,C ++和C#编程已有20多年了。我刚刚决定研究一下iPhone的开发以及Xcode和Objective-C。噢,我的天啊……所有有关Microsoft的投诉我都收回了,我现在意识到代码的糟糕程度。与C#相比,Objective-C过于复杂。我被C#宠坏了,现在我感谢Microsoft付出的所有辛苦工作。仅使用方法调用读取Objective-C很难理解。C#在这方面很优雅。那只是我的看法,我希望Apple开发语言像Apple产品一样好,但是亲爱的,他们有很多可以向Microsoft学习的东西。毫无疑问,C#.NET应用程序比XCode Objective-C可以使应用程序启动和运行的速度快很多倍。苹果公司当然应该从微软的书中摘取一片叶子,然后我们将拥有一个完美的环境。:-)


47
即使您浏览了一本iPhone开发手册,仍然能够在拥有20年经验的平台上更快地创建应用程序?AMAZING
库比什

25
我有和Waz完全一样的经历。在我开始学习Objective C之后,我也非常感谢Microsoft在C#和诸如Visual Studio之类的开发工具中所做的工作。
René

4
这也是我在研究Objective-c时(与c#相比过于复杂)的经验。@ alexy13您错过了原始消息中c和c ++的哪一部分?在一种语言家族中拥有数十年的经验可以帮助LOT评估使用同一家族的另一种语言完成同一工作的难易程度。
安德森·福塔雷萨

5
这个最佳答案如何?这不是一个简洁的答案,只是对他一夜之间学习的某种语言与他已经使用了20多年的一种语言的明显偏见……显然,您不会精通这种新语言
Heavy_Bullets 2014年

3
"Just reading Objective-C with method invokes is difficult to read"-这只是一个非常主观的论点,在这里被称为Obj-C的缺点。所有其他的说法都是有争议的。
skywinder 2014年

46

这里没有技术评论,但是我发现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)

目标C

NSMutableArray *strings = [NSMutableArray array];
[strings addObject:@"xyzzy"];
[strings addObject:@15];
NSString *x = strings[0];
[strings removeObjectAtIndex:0];

看起来糟透了。我什至尝试阅读其中的2本书,他们很早就迷了我,通常我不会通过编程书籍/语言来理解。

我很高兴我们拥有适用于Mac OS的Mono,因为如果我不得不依靠Apple为我提供良好的开发环境...


17
忽略第一行应该以结尾[NSMutableArray array](他正在泄漏内存)而第四行应该以NSString* xor 开头id x(编译错误)的事实……是的,Objective-C缺少泛型(老实说,我不会错过它们),您不会使用数组语法对对象进行索引,并且API通常较为冗长。可能的,要的。确实取决于您希望看到的内容。(您可以在C ++ STL中编写相同的代码,但我认为这太可怕了。)对我来说,可读的代码通常意味着代码的文本告诉您它在做什么,因此,Objective-C代码是更可取的。
奎因·泰勒

18
我确实没有发现语法方面的任何错误- 感觉可读性较差的主要原因是:1)对于C背景的每个人都不熟悉,以及2)在纯C结构的中间使用它,看起来很陌生。另一方面,Smalltalkish命名方法作为方法名称的一部分实际上使调用更加容易理解。实际上,您的C#代码示例很好地演示了这一点-无法编译,因为List<T>.Remove字符串作为参数,并删除了该字符串的首次出现。要按索引删除,您需要RemoveAt
帕维尔·米纳夫

12
...而带有的ObjC版本removeObjectAtIndex:虽然较为冗长,但对其功能也没有歧义。
帕维尔米纳夫

6
优胜者,帕维尔。同样,至少对于我来说,之间的不一致strings[0]和不strings.RemoveAt(0)清晰性。(而且,当方法名称以大写字母开头时,它总是让我感到烦恼……我知道这是个小问题,但那很奇怪。)
Quinn Taylor

4
以我为例,对于许多人来说,“工具”的可读性会影响我的生产率。我对许多语言(Objective-C)感到自在且富有成效,但是从来没有成为其中的一种,这并不是因为缺乏尝试。但同样,归根结底,这全都取决于个人喜好。与20年前不同,您不必为了目标平台Y而使用语言X。您可以选择最适合自己的语言。
TimothyP 2014年

17

手动内存管理是Objective-C的初学者似乎面临的最大问题,主要是因为他们认为它比实际要复杂。

Objective-C和Cocoa的扩展依赖于执行方面的惯例;知道并遵循一套非常小的规则,动态运行时您将免费获得很多回报。

不是100%真实的规则,但足以满足每天的需求是:

  • 每个对的调用alloc都应release在当前作用域的末尾与匹配。
  • 如果您的方法的返回值已通过获取,alloc则应返回return [value autorelease];而不是与匹配release
  • 使用属性,没有规则三。

下面是更长的解释。

内存管理基于所有权;只有一个对象实例的所有者应该永远释放对象,大家还应该总是什么都不做。这意味着在95%的代码中,您将Objective-C视为垃圾回收。

那么其他5%呢?您需要注意三种方法,从这些方法接收的任何对象实例均归当前方法范围所拥有:

  • alloc
  • 任何以单词new开头的方法,例如newor newService
  • 包含单词copy的任何方法,例如copymutableCopy

该方法在退出之前对其拥有的对象实例有三种处理方法:

  • release如果不再需要使用它来释放它。
  • 只需分配它即可将所有权赋予字段(实例变量)或全局变量。
  • 放弃所有权,但在实例消失之前通过致电给其他人获得所有权的机会autorelease

因此,什么时候应该主动致电来取得所有权retain?两种情况:

  • 在初始化程序中分配字段时。
  • 手动执行setter方法时。

2
+1出色的总结。听起来与我多年前学习C时非常相似。
亚历克斯·安加斯

4
需要说明的是,在Mac上,Objective-C完全支持垃圾收集,并且不需要执行任何手动内存管理。仅在iOS中需要手动内存管理。
PlagueHammer 2011年

3
尽管如此,如果只是在需要时提高性能(不必运行垃圾收集),那么学习内存管理的基础知识还是很不错的。
FeifanZ

3
iOS 5引入了ARC,从而无需手动释放已分配的对象。但是它仍然没有C#容易。您必须记住,Objective-C已有20多年的历史了,它在那时回避了一些语言要求:知道何时分配内存以及何时释放/释放内存。C#为您删除了所有这些。话虽这么说,可可拥有许多在Windows Phone中仍可访问的API。例如手势,涉及UI事件的更多控件等等……
jyavenard 2011年

10

当然,如果您一生中看到的所有东西都是目标C,那么它的语法似乎是唯一的可能。我们可以称您为“编程处女”。

但是,由于许多代码都是用C,C ++,Java,JavaScript,Pascal和其他语言编写的,因此您会发现ObjectiveC与所有代码都不同,但并不是很好。他们有这个理由吗?让我们看看其他流行的语言:

C ++为C增加了很多附加功能,但是它仅根据需要更改了原始语法。

与C ++相比,C#增加了很多附加功能,但它仅改变了C ++中难看的内容(例如从界面中删除“ ::”)。

Java进行了很多更改,但是除了需要更改的部分外,它保留了熟悉的语法。

JavaScript是一种完全动态的语言,可以完成ObjectiveC无法完成的许多工作。尽管如此,它的创建者并没有发明一种新的方法来调用方法和传递参数,只是与世界其他地区有所不同。

Visual Basic可以像ObjectiveC一样乱序传递参数。您可以命名参数,但也可以按常规方式传递参数。无论您使用什么,这都是每个人都能理解的普通逗号分隔方式。逗号是常用的分隔符,不仅在编程语言中,而且在一般的书籍,报纸和书面语言中都是这样。

对象Pascal的语法与C的语法不同,但是对于程序员来说,它的语法实际上更容易阅读(也许不是计算机可读的,而是计算机在乎谁的想法)。所以也许他们离题了,但至少他们的结果更好。

Python具有不同的语法,对于人类而言,它甚至比Pascal更易于阅读。因此,当他们更改它,使其与众不同时,至少它们对我们的程序员来说更好。

然后有ObjectiveC。对C进行了一些改进,但是发明了它自己的接口语法,方法调用,参数传递等等。我不知道他们为什么不互换+和-以便加号减去两个数字。它本来会更酷。

Steve Jobs通过支持ObjectiveC搞砸了。当然,他不能支持C#,后者更好,但属于他最差的竞争对手。因此,这是一项政治决定,而不是实际决定。当出于政治原因做出技术决定时,技术总会遭受损失。他应该领导自己擅长的公司,并将编程事务留给真正的专家。

我敢肯定,如果他决定以iOS以外的任何其他语言编写iOS并支持库,那么他肯定会为iPhone提供更多的应用程序。除了顽固的粉丝,处女的程序员和史蒂夫·乔布斯之外,每个人都觉得ObjectiveC荒唐,丑陋和令人反感。


3
最后两段总结了全部内容
Zakos 2014年

哦,是的,可以肯定该语法看起来很荒谬,但是Objective-C语言的精髓在于,它几乎是最容易使用所有语言的反射的语言,并且具有一些真正出色的运行时功能,这些功能使得几种范例的实现几乎微不足道。例如,在使用Objective-C时,我不必介意要使用哪个线性表-链表或向量,或仅NSArray此而已- 它可以根据机器和数据的性质来选择最佳算法。
2014年

我最初的工作是在Objective-C中实现iOS-App用户界面的(原始)程序员。我现在想要的(三年后)只是要退出那个孤独的“孤岛”,并学习一些与平台无关的东西,因此更具开创性。还可以了解其他框架是否也更新得如此之快和容易出错。嘿! 新功能!- 崩溃 ...希望(德国)工作中心为我花一些钱在Java和/或C ++ / C#上的教程上,因为我不再想为Apple sh * t开发。
anneblue '16

5

我对Objective-C钟爱的一件事是对象系统基于消息,它使您可以做一些您在C#中无法做的非常好的事情(至少要等到它们支持dynamic关键字后,它才能开始!)。

编写可可应用程序的另一个很棒的事情是Interface Builder,它比Visual Studio中的表单设计器好得多。

关于obj-c的事情(作为C#开发人员)让我烦恼的事实是,您必须管理自己的内存(有垃圾回收,但在iPhone上不起作用),并且由于以下原因它可能非常冗长选择器语法和所有[]。


2
dynamic只会使您半途而废-即使在C#4.0中,即使使用消息委派之类的琐碎事情,实现一个真正的动态对象也是乏味的。另一方面,传递la ObjC的灵活性,真正的动态消息的代价是丢失类型的安全性。
帕维尔·米纳夫

3
值得指出的是,Objective-C允许加入静态类型,这确实提供了更高的类型安全性。有些人喜欢编译时检查,有些人喜欢运行时检查。(在两种语言中)好处是选择不必是绝对的。
奎因·泰勒

3
Windows Forms设计器不是很好,但是如果您能够使用WPF(从.NET 3.0开始),则Expression Blend很难被击败……
Nate

您可以通过System.Reflection结合C#3.0中的扩展来执行很多操作,可以调用找到的任何方法,但不是真正的消息传递,它看起来像是obj.PassMessage("function_name", params object[] args);将更好的消息传递集成到语言中,在普通对象上缺少可调用的方法是需要。
菲利普·肯克

4

作为一个刚开始使用来自C#4.0的iPhone版Objective-C的程序员,我缺少lambda表达式,尤其是Linq-to-XML。Lambda表达式是特定于C#的,而Linq-to-XML实际上更像是.NET与Cocoa的对比。在我编写的一个示例应用程序中,我在字符串中有一些XML。我想将XML的元素解析为对象的集合。

为了在Objective-C / Cocoa中完成此任务,我不得不使用NSXmlParser类。此类依赖于另一个对象,该对象通过以下方法实现NSXMLParserDelegate协议,该方法在读取元素打开标签,读取某些数据(通常在元素内部)以及读取某些元素结束标签时调用(读取:发送消息) 。您必须跟踪解析状态和状态。老实说,我不知道如果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#所要求的相对缺乏冗长性。


重要的是,在此比较中,C#并没有太多“缺乏冗长性”,只有冗长性包含在您用来解析XML的.net框架类中。如果您检查其中的代码,则可能会发现更多的C#代码,甚至可能更冗长。
XIVSolutions 2011年

3

可能最重要的区别是内存管理。使用C#,由于它是一种基于CLR的语言,因此可以实现垃圾回收。使用Objective-C,您需要自己管理内存。

如果您来自C#背景(或与此相关的任何现代语言),那么迁移到没有自动内存管理的语言确实会很痛苦,因为您将花费大量的编码时间来正确地管理内存(并进行调试)。好)。


6
最近,ObjC已跟踪垃圾回收。另一方面,C#使您可以根据需要自己管理内存(由于使用了原始指针)。
帕维尔·米纳夫09年

3
我发现Objective-C中的手动内存管理(在Apple的框架下)并没有太大的负担:保留/释放/自动释放周期比C和C ++中的“传统”内存管理麻烦得多。
mipadi

5
DSO并不是真正的DSO-即使在非垃圾收集环境(如iPhone)上,保留/释放和自动释放的内容也需要大约10分钟的学习时间,然后再没问题。我发现许多C#-er喜欢夸大内存管理的挑战。几乎就像是他们担心否则会过分喜欢obj-c ...;)
h4xxr

4
手动内存管理的基础并不难。但是,当您开始传递分配的对象并且需要处理复杂的对象图时,它很快就会变得非常复杂,因为您需要仔细遵循规则,如谁负责释放对象以及何时释放对象。引用计数实现使它更容易一些,除了您需要处理对象图中的循环...与C#相比,所有这些IMO都有很大的不同。
DSO

1

这是一篇比较这两种语言的不错的文章:http : //www.coderetard.com/2008/03/16/c-vs-objective-c/


很遗憾,该页面声称使用的是UTF-8,但是对于撇号和引号有各种讨厌的替代方法。我认为他的文字使用了“曲线”引号,但它们确实使代码乱码...
Quinn Taylor

他们似乎偷走了他们的介绍生猪,但即使是源文章也对其代码进行了修改。也不是特别好的文章。
dnord

-2

除了两种语言在范式上的差异外,没有太多差异。就像我讨厌说的那样,您可以使用.NET和C#进行与Objective-C和Cocoa相同的事情(可能不那么容易)。作为豹,Objective-C的2.0有垃圾收集,所以你不要,除非你想(代码兼容旧的Mac和iPhone的应用程序都需要2个原因)自己管理内存。

就结构化的可读代码而言,程序员和任何其他语言一样,负担很大。但是,我发现消息传递范例非常适合可读代码,只要您适当地命名函数/方法(同样,就像其他任何语言一样)即可。

我将第一个承认我对C#或.NET不太熟悉。但是上面列出的Quinn的原因是我不在乎成为的很多原因。


-3

obj-c中使用的方法调用使代码易于阅读,在我看来,它比c#更优雅,并且obj-c构建在c之上,因此所有c代码在obj-c中都可以正常工作。对我而言,最大的卖主是obj-c是一个开放标准,因此您可以找到任何系统的编译器。


2
ISO C#也是一个开放标准。而且,据我所知,唯一存在的ObjC编译器是gcc。
帕维尔·米纳夫09年

@Pavel:还有可移植对象编译器(users.telenet.be/stes/compiler.html)和clang。
mipadi

1
实际上,GCC不再是唯一的编译器— Clang和LLVM是为替代GCC而设计和开发的一对技术,它们完成了包括JIT编译在内的所有工作。这是Snow Leopard中OpenCL的核心。它们还可以扩展到其他语言,并且值得一试。
奎因·泰勒

2
老实说,我不认为可移植性是Objective-C的专业版。相反,优点更多的是快速开发和减少代码量来完成同一任务。
奎因·泰勒

感谢您纠正我关于编译器可用性的错误。嗯,无论如何从技术上讲,可移植性都是存在的-例如,我可以在Win32上很好地使用MinGW / ObjC-在这种意义上,它与gcc一样可移植。当然,这些库不会存在(尽管...是否有GnuStep / Win32?),但是这种情况并没有比Mono的情况差很多。所以总的来说,我想说可移植性对任何一方都不是重点。
帕维尔·米纳夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.