「もしあなたが知っている唯一の言語がJavaまたはC#であるなら、私はあなたがプロのプログラマーだとは思わない-あなたはこれまでたった1種類のツリーで作業した若い大工のようだ。」
おじさんボブ数ヶ月前、私はiPhone用のアプリケーションの開発を始めました。 .NETプラットフォームとC#からCocoaとObjective-Cへの切り替えは冒険なしではありませんでしたが、非常に興味深く有益でした。 すぐに、当社の他の開発者が新しいプラットフォームを開発するのを手伝わなければなりません。 そのため、この移行をよりスムーズにするための一連の導入ノートを作成することにしました。
この記事では、C#開発者の観点からObjective-Cに関する事実の小さなセットを提供します。
- Objective-Cは、オブジェクト指向言語であり、C言語の「正直な」拡張です(Cで記述されたプログラムは、Objective-Cのプログラムです。たとえば、C ++の場合は必ずしも当てはまりません)。
言語についての十分な詳細は、 Objective-Cの最近の記事にゼロから書かれています。 - オブジェクトを記述するために2つのファイルが作成されます。拡張子が.hのヘッダーファイルと拡張子が.mの実装ファイルです。
- Objective-Cクラスはオブジェクトです。大まかに言うと、Objective-Cクラスは、静的メソッドのセットを持つファクトリメソッドパターンの実装として表すことができます。
- C#のような多重継承はサポートされていません。
- NSObjectは、.NETの基本クラスSystem.Objectの「アナログ」です。
- Objective-Cでインターフェイスを記述するとき、クラスC#を意味します。
- そして、C#でインターフェイスと呼ぶもの、Objective-Cプロトコルではプロトコルと呼びます。
- Objective-Cには、クラスメソッド(+で宣言を開始する)とインスタンスメソッド(宣言は-で始まる)の2種類のメソッドがあります。 理解しているように、クラスメソッドは同じ静的C#メソッドです。
- オブジェクトメソッドを呼び出す場合は、オブジェクトメソッドに関するメッセージを送信します(Objective-Cは、関数指向のC#とは異なり、メッセージ指向の言語です)。
- Objective-Cでは、すべてのメソッドがパブリックです(より正確には、アクセスレベルによるメソッドの分離はありません)。
- Objective-Cでは、すべてのメソッドは仮想です(つまり、派生クラスで任意のメソッドをオーバーライドできます)。
- 残念ながら、Objective-Cにはガベージコレクターがありません(iPhone用のプログラミングの場合)。 代わりに、リンクカウントメカニズムが使用されます。
- 使用するプロパティを取得するには、ヘッダーファイルで@propertyキーワードを使用してプロパティを宣言し、実装ファイルで@syntesizeを使用してゲッターとセッターを生成します。
- #importが使用しています
- selfはこれへのポインタです
- スーパーはベースです
- idはオブジェクトのようなものです
メッセージを送信する
一般に、Objective-Cでメッセージを送信するアプローチと、その結果、メソッドの命名方法は全体的な哲学です。 ハブには
、Objective-Cのメソッドを見た人々が目を失ったという投稿がすでにありました。 この記事は、それらを押し戻そうとする人々のためのものです。 これを行う最も簡単な方法は、なじみのあるものとの類似性を確認することです。
Objective-Cでメソッド呼び出しがどのように見えるか見てみましょう。 各例では、C#の実際のアナログが与えられます。
パラメータなしのメソッド:
C#:
someString。 ToLower ( ) ;
Objective-C:
[ someString ToLower ] ;
1つのパラメーター:
someString。 等しい ( anotherString ) ;
[ someString isEqualToString : anotherString ] ;
いくつかのオプション:
someString。 EndsWith ( anotherString、 true 、someCulture ) ;
[ someString isEndedWithString : anotherString withIgnoreCase : YES andCultureInfo : someCulture ] ;
添付メッセージ:
someString。 サブストリング ( 1 ) 。 EndsWith ( anotherString。Trim ( ) 、 true 、CultureInfo.CurrentCulture ) ;
[ [ someString getSubstringStartedAtIndex : 1 ] isEndedWith : [ anotherString Trim ] withIgnoreCase : YES andCultureInfo : [ CultureInfo getCurrentCulture ] ] ;
上記のように、Objective-Cにはインスタンスメソッドとクラスメソッドの2種類のメソッドがあります。 C#とObjective-Cでどのように宣言されているか見てみましょう。
インスタンスメソッド:
public int sum ( int firstNumber、 int secondNumber ) ;
- ( int ) sumOfFirstNumber : ( int ) firstNumberおよびSecondNumber : ( int ) secondNumber;
クラスメソッド(またはC#の静的メソッド):
静的 int長さ( 文字列 str ) ;
+ ( int )長さ: ( NSString * ) str;
デザイナーとデストラクタについて少し
C#と同様に、新しいキーワードを使用してオブジェクトを作成できます。
[ someObject new ] ;
この方法は、次の操作に似ています。
[ [ someObject alloc ] init ] ;
allocはオブジェクトにメモリを割り当て、initはいくつかのデフォルトパラメータでメモリのこのセクションを初期化します。 C#では、コンストラクターを呼び出すときに、これらの操作は論理的に分離されていません。
2番目のアプローチを使用することをお勧めします。これは、オブジェクトを作成するメカニズムをより正確に示すためです(そして、何をしているのかを理解する必要がありますか?)。
[ [ someObject alloc ] initWithTitle : @ "SomeTitle" ] ;
NSStringクラスのいくつかのコンストラクターの宣言の例を次に示します。
- ( id ) init ;
文字を含まない初期化されたNSStringオブジェクトを返します。
- ( id ) initWithString : ( NSString * ) aString ;
初期化されたNSStringオブジェクトを返し、別のNSStringオブジェクトから文字をコピーします。
- ( id ) initWithCharacters : ( const unichar * )文字の長さ: ( NSUInteger )長さ;
指定された文字配列から指定された数の文字を含む初期化されたNSStringオブジェクトを返します。
initがObjective-Cのコンストラクタ(またはalloc + initの束)である場合、deallocはデストラクタ(メモリの解放)です。 C#の場合と同様に、自動的に呼び出されます。
そして、リンクカウンターについて少し
C#から移行する場合、Objective-Cで開発するときのメモリ管理は最も重要な問題の1つです。 私たち(.NET開発者)はこの意味で甘やかされています-ほとんどの場合、ガベージコレクターがすべてを行ってくれるという事実に慣れています。 このアプローチはここでは機能しません。アプリケーションのメモリを慎重に操作しないと、「奇妙な」エラーが定期的に発生します。
リンクカウンターメカニズムは、すべてのオブジェクトに対して基本的なNSObjectを実装します。 考え方は次のとおりです。各オブジェクトには参照カウンターが含まれており、リンクの数がゼロになると、deallocが呼び出されます。 自分でdeallocを呼び出さないでください!
オブジェクトのメモリを割り当てる(alloc / newメソッドを呼び出す)とき、オブジェクトのコピーを作成するとき(コピーメッセージ)、保持メッセージ付きのオブジェクトを送信するとき、カウンタ値は1ずつ増加します。 カウンタ値を1減らすには、オブジェクトにリリースメッセージを送信する必要があります。
通常、オブジェクトを操作するスキームは次のとおりです:作成(参照カウンターを1つ増やします)、必要なアクションを実行(すべての対象オブジェクトがメッセージを保持してから解放)し、解放メッセージを送信(カウンターを1つ減らし)、デストラクタが呼び出されます。
リリースメッセージでは、オブジェクトのデストラクタを再呼び出しするとプログラムが削除されるため、注意して不要な呼び出しを避ける必要があります。
また、オブジェクトにリリースメッセージを送信する必要があることを覚えておく必要性を取り除くことも可能です(これは、オブジェクトがメソッドによって返され、将来の運命がわからないことが原因である場合があります)。 これは、autoReleaseメッセージとAutoreleasePoolオブジェクトを使用して実行できます。
[ [ [ someObject alloc ] init ] autorelease ] ;
オブジェクトはAutoreleasePoolに書き込まれます。 つまり、リリースメッセージは「後で」オブジェクトに送信され、それまでオブジェクトはメモリ内にあります。 「しばらくしてから」は、リリースまたはドレインメッセージがAutoreleasePoolオブジェクトに送信されたときに発生します。
このトピックの続きとして、Shivani Khannaによる最近のレポート
「Objective C for C#Developers」を参照することをお勧めします。
追加/修正を歓迎します。
記事を読んでくれてありがとう!