web-dev-qa-db-ja.com

Objective-CはC#と比較してどうですか?

最近、Macを購入し、主にVMWare FusionでのC#開発に使用しています。 Nice Macアプリケーションがすべて揃っているので、インストールのクリックだけでXcodeに潜み、Objective-Cを学習することを考え始めました。

おそらくObjective-Cの起源はCであり、C#の起源はJava/C++であるため、2つの言語の構文は大きく異なります。ただし、さまざまな構文を学習できるため、問題ありません。

私の主な関心事は、言語での作業と、それが適切に構造化された読みやすくエレガントなコードの生成に役立つかどうかです。私はC#のLINQやvarなどの機能を本当に楽しんでおり、Objective-Cに同等の機能やより良い/異なる機能があるのではないかと考えています。

Objective-Cを使用した開発で見逃す言語機能は何ですか?獲得できる機能は何ですか?

編集:フレームワークの比較は便利で興味深いですが、language比較はこの質問が本当に求めているものです(一部は私のせいです)元々.netでタグ付けされています。おそらく、Cocoaと.NETはどちらも非常にリッチなフレームワークであり、どちらもMac OS XとWindowsを対象とする目的を持っています。

これまでに考え抜かれた、合理的にバランスのとれた視点をありがとう!

86
Alex Angas

すべてのタスクに最適な言語はなく、Objective-Cも例外ではありませんが、非常に具体的な利点がいくつかあります。 LINQvar(直接の置換には気づいていない)を使用するように、これらの一部は厳密に言語関連であり、その他はフレームワーク関連です。

注: C#が.NETと密結合しているように、Objective-CはCocoaと密結合しています。したがって、私のポイントのいくつかはObjective-Cとは無関係に見えるかもしれませんが、CocoaなしのObjective-Cは.NET/WPF/LINQなしのC#に似ており、Monoで実行されています。これは、物事が通常行われる方法ではありません。

違い、長所、短所を完全に詳述するふりをするつもりはありませんが、ここで心に浮かぶものがあります。

  • Objective-Cの最良の部分の1つは動的な性質です。メソッドを呼び出すのではなく、ランタイムが動的にルーティングするメッセージを送信します。 (賢明に)動的型付けと組み合わせると、これにより多くの強力なパターンをより簡単に、または実装するのも簡単にできます。

  • Cの厳密なスーパーセットとして、Objective-Cは、あなたが何をしているかを知っていることを信頼しています。 C#やJavaのような言語のマネージドアプローチやタイプセーフアプローチとは異なり、Objective-Cを使用すると、望みどおりの結果を得ることができます。これは明らかに危険な場合がありますが、言語が積極的にあなたのほとんどのことを妨げることはないという事実は非常に強力です。 (EDIT: C#には「安全でない」機能もありますが、デフォルトの動作はマネージコードであり、明示的にオプトアウトする必要があります。比較して、Java onlyはタイプセーフなコードを許可し、Cや他の方法で生のポインタを決して公開しません。)

  • カテゴリ(サブクラス化やソースへのアクセスなしでクラスにメソッドを追加/変更する)は、素晴らしい両刃の剣です。継承階層を大幅に簡素化し、コードを削除できますが、何かおかしなことをすると、結果が困惑することがあります。

  • Cocoaを使用すると、GUIアプリの作成がさまざまな方法ではるかに簡単になりますが、パラダイムに頭を包む必要があります。 MVC設計はCocoaに広く普及しており、デリゲート、通知、マルチスレッドGUIアプリなどのパターンは、Objective-Cに適しています。

  • Cocoaバインディングとキー値監視により、大量のグルーコードを削除でき、Cocoaフレームワークはこれを広範囲に活用します。 Objective-Cの動的ディスパッチはこれと連動して動作するため、キー値に準拠している限り、オブジェクトのタイプは重要ではありません。

  • ジェネリックと名前空間を見逃す可能性があり、それらには利点がありますが、Objective-Cの考え方とパラダイムでは、それらは必要というよりはむしろ素晴らしいものになります。 (ジェネリックはすべて型の安全性とキャストの回避に関するものですが、Objective-Cでの動的な型指定は本質的にこれを問題にしません。うまくいけば名前空間はいいでしょうが、それはコストが間違いなく利益を上回る競合を避けるのに十分単純です、特にレガシーコード用。)

  • 並行性については、ブロック(Snow Leopardの新しい言語機能であり、多数のCocoa APIに実装されています)は非常に便利です。数行(10.6のlibsystemの一部であるGrand Central Dispatchと頻繁に結合)は、コールバック関数、コンテキストなどの重要な定型文を削除できます(ブロックはCおよびC++でも使用でき、C#に追加できますが、 NSOperationQueueは、GNSが1つ以上の異なるスレッドで自動的に実行するカスタムNSOperationサブクラスまたは匿名ブロックをディスパッチすることにより、独自のコードに並行性を追加する非常に便利な方法でもあります。

89
Quinn Taylor

私はC、C++、C#で20年以上プログラミングを始め、1990年に始めました。iPhoneの開発とXcodeとObjective-Cを見ることにしました。私の良さ...私が取り戻したマイクロソフトについてのすべての不満は、コードがどれほど悪いものであったかを今理解しています。 Objective-Cは、C#の機能に比べて非常に複雑です。私はC#に甘やかされており、今ではMicrosoftが行ったすべての苦労に感謝しています。メソッド呼び出しでObjective-Cを読むだけでは読みにくいです。これでC#はエレガントです。それは私の意見です。Apple開発言語は、Apple製品と同じですが、親愛なる、彼らは多くのことを学ぶことができます。マイクロソフト。C#.NETアプリケーションに疑問はありません。XCodeObjective-Cよりも何倍も高速にアプリケーションを起動して実行できます。Apple完璧な環境があります。:-)

54
Waz

ここには技術的なレビューはありませんが、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冊の本を読んでも試してみましたが、それらは早い段階で私を失いました、そして、通常私はプログラミング本/言語でそれを得ません。

Appleを使って優れた開発環境を提供しなければならなかったので、Mac OS用のMonoができてうれしいです...

46
TimothyP

手動メモリ管理は、Objective-Cの初心者にとって最も問題があるようです。これは、主に、それが実際よりも複雑だと考えているためです。

Objective-CとCocoaは、拡張により、施行よりも慣習に依存しています。非常に小さなルールのセットを知って従うと、見返りに動的なランタイムによって多くのことを無料で得ることができます。

100%の真のルールではありませんが、日常的に十分です:

  • allocへの呼び出しはすべて、現在のスコープの最後でreleaseと一致する必要があります。
  • メソッドの戻り値がallocによって取得されている場合、releaseと一致するのではなく、return [value autorelease];によって返される必要があります。
  • プロパティを使用します。ルール3はありません。

長い説明が続きます。

メモリ管理は所有権に基づいています。 onlyオブジェクトインスタンスの所有者はオブジェクトを解放する必要があります。everybody elseは常に何も実行しません。つまり、すべてのコードの95%で、Objective-Cをガベージコレクションのように扱っています。

他の5%はどうですか?注目すべき3つのメソッドがあります。これらのメソッドから受け取ったオブジェクトインスタンスは、現在のメソッドスコープによって所有されます。

  • alloc
  • newnewServiceなど、Wordnewで始まるメソッド。
  • copymutableCopyなど、Wordのコピーを含むメソッド。

このメソッドには、終了前に所有オブジェクトインスタンスをどう処理するかについて、3つの可能なオプションがあります。

  • 不要になった場合は、releaseを使用してリリースします。
  • フィールド(インスタンス変数)、または単純に割り当てることでグローバル変数に所有権を与えます。
  • 所有権を放棄しますが、autoreleaseを呼び出して、インスタンスがなくなる前に他の誰かに所有権を取得する機会を与えます。

では、いつretainを呼び出して先を見越して所有権を取るべきでしょうか? 2つのケース:

  • 初期化子でフィールドを割り当てるとき。
  • セッターメソッドを手動で実装する場合。
17
PeyloW

確かに、あなたが人生で見たものがすべてObjective Cである場合、その構文は可能な限りのように見えます。私たちはあなたを「プログラミング処女」と呼ぶことができます。

しかし、多くのコードはC、C++、Java、JavaScript、Pascalなどの言語で記述されているため、ObjectiveCはすべての言語とは異なるが、良い方法ではないことがわかります。彼らにはこの理由がありましたか?他の一般的な言語を見てみましょう:

C++はCに多くの追加機能を追加しましたが、必要なだけ元の構文を変更しました。

C#は、C++と比較して多くの追加機能を追加しましたが、C++で見苦しいものだけを変更しました(インターフェイスから「::」を削除するなど)。

Javaは多くのことを変更しましたが、変更が必要な部分を除き、使い慣れた構文を保持していました。

JavaScriptは完全に動的な言語であり、ObjectiveCではできない多くのことを実行できます。それでも、その作成者は、メソッドを呼び出したり、パラメーターを渡す新しい方法を発明しませんでした。

Visual Basicは、ObjectiveCと同様に、パラメーターを順序どおりに渡すことができます。パラメーターに名前を付けることができますが、通常の方法で渡すこともできます。使用するものは何でも、それは誰もが理解できる通常のカンマ区切りの方法です。コンマは、プログラミング言語だけでなく、本、新聞、一般的な書き言葉でも通常の区切り文字です。

Object Pascalの構文はCとは異なりますが、実際にはその構文はプログラマーにとって読みやすいです(コンピューターではなく、コンピューターが何を考えているかを気にする人)。だから彼らは脱線したかもしれないが、少なくとも彼らの結果はより良い。

Pythonには異なる構文があり、Pascalよりも(人間にとって)読みやすくなっています。だから彼らがそれを変えて、それを変えたとき、少なくとも彼らは私たちプログラマーにとってそれを良くした。

そして、ObjectiveCがあります。 Cにいくつかの改善を追加しますが、独自のインターフェイス構文、メソッド呼び出し、パラメーターの受け渡しなどを発明します。なぜ+と-を交換しなかったのだろうか?もっとかっこよかったです。

Steve JobsはObjectiveCをサポートすることで失敗しました。もちろん、彼はC#をサポートできません。これは優れていますが、彼の最悪のライバルに属しています。したがって、これは政治的な決定であり、実際的な決定ではありません。技術的な決定が政治的な理由で行われる場合、技術は常に苦しみます。彼は会社を率いるべきであり、彼はそれをうまく行い、プログラミングの問題は本当の専門家に任せるべきです。

IOSを作成し、ObjectiveC以外の言語でライブラリをサポートすることに決めた場合、iPhone用のアプリがさらに増えると確信しています。頑固なファン、バージンプログラマー、スティーブジョブズを除くすべての人にとって、ObjectiveCはばかげて、ugく、反発的に見えます。

10
user561168

Objective-Cで気に入っていることの1つは、オブジェクトシステムがメッセージに基づいていることです。これにより、C#ではできなかった素晴らしい操作を(少なくとも動的キーワードがサポートされるまで!)実行できます。

ココアアプリの作成に関するもう1つの優れた点は、Interface Builderです。VisualStudioのフォームデザイナーよりもはるかに優れています。

Obj-cについて私を悩ます(C#開発者として)のは、自分のメモリを管理しなければならないという事実(ガベージコレクションがありますが、iPhoneでは機能しません)と、セレクター構文とすべての[]。

5
jonnii

C#4.0以降、Objective-C for iPhoneを使い始めたばかりのプログラマーとして、ラムダ式、特にLinq-to-XMLが欠落しています。ラムダ式は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#で必要な冗長性の相対的な欠如を示すための例にすぎません。

4
brentlightsey

おそらく最も重要な違いはメモリ管理です。 C#を使用すると、CLRベースの言語であるため、ガベージコレクションを取得できます。 Objective-Cでは、メモリを自分で管理する必要があります。

C#のバックグラウンド(または最新の言語)から来ている場合、メモリの適切な管理に多くのコーディング時間を費やすため、自動メモリ管理なしの言語に移行するのは本当に痛いでしょうまあ)。

3
DSO

以下に、2つの言語を比較した非常に優れた記事を示します。 http://www.coderetard.com/2008/03/16/c-vs-objective-c/

1
Cinder6