Objective-C

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ

Objective-C
家族C
によって設計されたトム・ラブとブラッド・コックス
初登場1984 ; 38年前 (1984
安定リリース
2.0 [1]
規律の入力静的動的弱い
OSクロスプラットフォーム
ファイル名拡張子.h、.m、.mm、.M
Webサイトdeveloper.apple.com
主な実装
ClangGCC
に影響を受けた
CSmalltalk
影響を受ける
GroovyJavaNuObjective-JTOMSwift [2]

Objective-Cは、Cプログラミング言語にSmalltalkスタイルのメッセージング追加する汎用オブジェクト指向 プログラミング言語です。もともとは1980年代初頭にBradCoxとTomLoveによって開発されましたがNeXTSTEPオペレーティングシステムとしてNeXTによって選択されました。Objective-Cは、それぞれのアプリケーションプログラミングインターフェイス(API)であるCocoaを使用してmacOS (NeXTSTEP [3]から派生)およびiOSアプリケーションを開発するためにAppleがサポートする標準プログラミング言語でした。CocoaTouch、2014年にSwiftが導入されるまで。 [4]

Apple以外のオペレーティングシステム用に開発されたObjective-Cプログラム、またはAppleのAPIに依存しないプログラムは、GNUGCCまたはLLVM / Clangサポートれている任意のプラットフォーム用にコンパイルすることもできます。

Objective-Cのソースコード「メッセージング/実装」プログラムファイルの拡張子は通常.mですが、Objective-Cの「ヘッダー/インターフェース」ファイルの拡張子は.hで、 Cヘッダーファイルと同じです。Objective-C ++ファイルは、.mmファイル拡張子で示されます。

歴史

Objective-Cは、1980年代初頭にBradCoxとTomLoveによって、彼らの会社であるProductivity Products International(PPI)で主に作成されました。[5]

彼らの会社の設立に至るまで、どちらも1981年にITTコーポレーションのプログラミングテクノロジーセンターにいる間にSmalltalkに紹介されていました。Objective-Cの初期の作業はその頃にさかのぼります。[6] Coxは、ソフトウェアの設計とプログラミングにおける真の再利用性の問題に興味をそそられました。彼は、Smalltalkのような言語が、ITTのシステム開発者向けの開発環境を構築する上で非常に貴重であることに気づきました。ただし、彼とTom Loveは、Cとの下位互換性がITTの通信エンジニアリング環境において非常に重要であることも認識していました。[7]

Coxは、Smalltalkの機能の一部を追加するために、 C用のプリプロセッサの作成を開始しました。彼はすぐに、 C言語へのオブジェクト指向拡張の実用的な実装を手に入れました。これは、オブジェクト指向プリコンパイラーの「OOPC」と呼ばれていました。[8] Loveは1982年にSchlumbergerResearchに雇われ、Smalltalk-80の最初の商用コピーを取得する機会があり、それが彼らの発案の発展にさらに影響を与えました。Coxは、実際の進歩が見込めることを実証するために、互換性のあるソフトウェアコンポーネントを作成することを示しました。実際には、既存のツールにいくつかの実用的な変更を加えるだけで済みました。具体的には、オブジェクトを柔軟にサポートし、使用可能なライブラリセットが提供され、コード(およびコードに必要なリソース)を1つのクロスプラットフォーム形式にバンドルできるようにする必要がありました。

LoveとCoxは、Objective-Cコンパイラとクラスライブラリを組み合わせた製品を商品化するために、最終的にPPIを形成しました。1986年に、Coxは、 Object-Oriented Programming、An Evolutionary Approachの本で、Objective-Cの主な説明を元の形式で公開しました彼は、Objective-Cが提供するものだけでなく、再利用性の問題にも多くの問題があることを注意深く指摘しましたが、この言語は、他の言語と機能を比較することがよくありました。

NeXTによる普及

1988年、NeXTはStepStone(Objective-C商標の所有者であるPPIの新しい名前)からObjective-Cのライセンスを取得し、Objective-CをサポートするようにGCCコンパイラを拡張しました。NeXTは、 NeXTSTEPユーザーインターフェイスとInterfaceBuilderのベースとなるAppKitおよびFoundationKitライブラリを開発しました。NeXTワークステーションは市場に大きな影響を与えることができませんでしたが、ツールは業界で広く賞賛されました。これにより、NeXTはハードウェアの生産を中止し、ソフトウェアツールに集中し、カスタムプログラミングのプラットフォームとしてNeXTSTEP(およびOPENSTEP)を販売しました。

GPLの条件を回避するために、NeXTはもともとObjective-Cフロントエンドを個別に出荷することを意図しており、ユーザーがそれをGCCとリンクしてコンパイラ実行可能ファイルを生成できるようにしました。当初はRichardM。Stallmanによって受け入れられましたが、StallmanがGNUの弁護士と相談し、NeXTがObjective-CをGCCの一部にすることに同意したため、この計画は却下されました。[9]

GCCを拡張する作業は、StepStoneからNeXTに参加したSteveNaroffが主導しました。コンパイラの変更はGPLライセンス条項に従って利用可能になりましたが、ランタイムライブラリは利用できなかったため、オープンソースの貢献は一般の人々には使用できなくなりました。これにより、他の関係者がオープンソースライセンスの下でそのようなランタイムライブラリを開発することになりました。その後、Steve Naroffは、AppleでClangのObjective-Cフロントエンドを構築するための主要な貢献者でもありました

GNUプロジェクトは、 OpenStep標準に基づいたGNUstepという名前のCocoaのフリーソフトウェア実装の作業を開始しました。[10] DennisGlattingは1992年に最初のGNUObjective-Cランタイムを作成しました。1993年から使用されているGNUObjective-Cランタイムは、Kresten KrabThorupがデンマークの大学生のときに開発したものです[要出典] Thorupは1993年から1996年までNeXTでも働いていました。[11]

AppleデベロップメントとSwift

1996年にNeXTを買収した後、AppleComputerは当時の新しいオペレーティングシステムであるMacOSXでOpenStepを使用しましたこれには、Objective-C、NeXTのObjective-Cベースの開発者ツールであるProject Builder、およびそのインターフェイス設計ツールであるInterfaceBuilderが含まれていました。両方とも後で1つのアプリケーションXcodeにマージされました。Appleの現在のCocoaAPIのほとんどは、OpenStepインターフェイスオブジェクトに基づいており、アクティブな開発に使用されている最も重要なObjective-C環境です。

WWDC 2014で、Appleは新しい言語Swiftを導入しました。これは、「Objective-C withouttheC」として特徴付けられています。

構文

Objective-CはCの最上位の薄層であり、 Cの「厳密なスーパーセット」です。つまり、Objective-Cコンパイラを使用して任意のCプログラムをコンパイルし、Objective-Cクラス内にC言語コードを自由に含めることができます。[12] [13] [14] [15] [16] [17]

Objective-Cは、そのオブジェクト構文をSmalltalkから派生させています非オブジェクト指向操作(プリミティブ変数、前処理、式、関数宣言、関数呼び出しを含む)の構文はすべて、Cの構文と同じですが、オブジェクト指向機能の構文はSmalltalk-の実装です。スタイルメッセージング。

メッセージ

オブジェクト指向プログラミングのObjective-Cモデルは、オブジェクトインスタンスへのメッセージパッシングに基づいています。Objective-Cでは、メソッドを呼び出しません1つはメッセージを送信しますこれは、 C ++で使用されるSimulaスタイルのプログラミングモデルとは異なりますこれら2つの概念の違いは、メソッドまたはメッセージ名によって参照されるコードの実行方法にあります。Simulaスタイルの言語では、ほとんどの場合、メソッド名はコンパイラによってターゲットクラスのコードのセクションにバインドされます。SmalltalkおよびObjective-Cでは、メッセージのターゲットは実行時に解決され、受信オブジェクト自体がメッセージを解釈します。メソッドはセレクターによって識別されますまたはSEL—各メッセージ名の一意の識別子。多くの場合、その名前を表すNULで終了する文字列であり、それを実装するCメソッドポインタ( IMP )に解決されます。[18]この結果、メッセージパッシングシステムには型チェックがありません。メッセージの送信先のオブジェクト(受信者)は、メッセージに応答することが保証されていません。応答しない場合は、例外が発生します。[19]

ポインタobjが指すオブジェクトにメッセージメソッドを送信するには、 C ++で次のコードが必要になります

obj- >メソッド引数);

Objective-Cでは、これは次のように記述されています。

[ objメソッド引数]; 

「メソッド」呼び出しは、コンパイラーによって実行時関数のobjc_msgSend(id self、SEL op、...)ファミリーに変換されます。さまざまな実装が、superのような最新の追加を処理します。[20] GNUファミリーでは、この関数はobjc_msg_sendvという名前ですが、 objc_msg_lookupの下の最新のルックアップシステムのために非推奨になりました[21]

どちらのプログラミングスタイルにも長所と短所があります。Simula(C ++)スタイルのオブジェクト指向プログラミングでは、可能な限りコンパイル時バインディングを使用することで、多重継承と高速実行が可能ですが、デフォルトでは動的バインディングをサポートしていません。また、抽象的でない限り、すべてのメソッドに対応する実装を強制しますObjective-Cで使用されているSmalltalkスタイルのプログラミングでは、メッセージを実装せずに、実行時にメソッドを実装に解決できます。たとえば、メッセージをオブジェクトのコレクションに送信すると、実行時エラーが発生することを恐れずに、一部のオブジェクトにのみ応答することが期待されます。メッセージパッシングでは、コンパイル時にオブジェクトを定義する必要もありません。派生オブジェクトでメソッドを呼び出すには、実装が必要です。動的(遅延)バインディングのその他の利点については、以下 の動的型付けのセクションを参照してください。)

インターフェースと実装

Objective-Cでは、クラスのインターフェイスと実装が個別に宣言されたコードブロックに含まれている必要があります。慣例により、開発者はインターフェイスをヘッダーファイルに配置し、実装をコードファイルに配置します。ヘッダーファイル(通常は.hのサフィックスが付いています)はCヘッダーファイルに似ていますが、実装(メソッド)ファイル(通常は.mのサフィックスが付いています)はCコードファイルに非常に似ています。

インターフェイス

これは、C ++やPythonなどの他のオブジェクト指向言語で使用されるクラス宣言に類似しています。

クラスのインターフェースは通常、ヘッダーファイルで定義されます。一般的な規則は、クラスの名前にちなんでヘッダーファイルに名前を付けることです。たとえば、Ball.hにはクラスBallのインターフェイスが含まれます

インターフェイス宣言の形式は次のとおりです。

@interface  classname  :superclassname  {
  //インスタンス変数
}
+  classMethod1 ;
+  return_type classMethod2 ;
+  return_type classMethod3:param1_type param1_varName ;

-  return_type instanceMethod1With1Parameter:param1_type param1_varName ;
-  return_type instanceMethod2With2Parameters:param1_type param1_varName
                              param2_callName:param2_type param2_varName ;
@終わり

上記で、プラス記号はクラスメソッド、またはクラス自体(インスタンスではなく)で呼び出すことができるメソッドを示し、マイナス記号はクラスの特定のインスタンスでのみ呼び出すことができるインスタンスメソッドを示します。クラスメソッドもインスタンス変数にアクセスできません。

上記のコードは、次のC ++インターフェイス とほぼ同等です。

クラス クラス名public superclassname {    
保護
  // インスタンス変数

パブリック
  //クラス(静的)関数
static void * classMethod1 ();    
  static return_type classMethod2 ();  
  static return_type classMethod3 param1_type param1_varName );   

  //インスタンス(メンバー)関数
return_type instanceMethod1With1Parameter param1_type param1_varName );    
  return_type
  instanceMethod2With2Parameters param1_type param1_varName  
                                 param2_type param2_varName = default );   
};

instanceMethod2With2Parameters:param2_callName:は、C / C ++に直接相当するものがない、引数式を使用したセレクターセグメントのインターリーブを示して いることに注意してください。

戻り値の型は、任意の標準C型、ジェネリックObjective-Cオブジェクトへのポインター、NSArray *、NSImage *、NSString *などの特定の型のオブジェクトへのポインター、またはメソッドが属するクラスへのポインターです。 (インスタンスタイプ)。デフォルトのリターンタイプは、一般的なObjective-CタイプIDです。

メソッド引数は、メソッド名の一部である引数にラベルを付ける名前で始まり、コロン、括弧内の予想される引数タイプ、および引数名が続きます。ラベルは省略できます。

-  void setRangeStart:int start end:int end ; 
-  void importDocumentWithName:NSString * name 
      withSpecifiedPreferences :(リファレンス* 設定 
                    beforePage:int insertPage ;

インターフェイス定義の派生物はカテゴリです。これにより、既存のクラスにメソッドを追加できます。[22]

実装

インターフェイスはクラスインターフェイスのみを宣言し、メソッド自体は宣言しません。実際のコードは実装ファイルに記述されます。実装(メソッド)ファイルのファイル拡張子は通常.m、元々「メッセージ」を意味していました。[23]

@implementation  classname
+  return_type classMethod { 
  //実装
}
-  return_type instanceMethod { 
  //実装
}
@終わり

メソッドは、インターフェース宣言を使用して記述されています。Objective-CとCの比較:

-  int メソッド:int i { 
  return [ self square_root i ];  
}
int関数int i {   
  square_root i );を返します。 
}

この構文では、引数の疑似命名が可能です。

-  void changeColorToRed :( float red green :( float green blue :( float blue {   
  // ...実装... 
}

//そのように呼び出されます:
[ myColor changeColorToRed 5.0 green 2.0 blue 6.0 ];   

メソッドの内部表現は、Objective-Cの実装ごとに異なります。myColorがColorクラスの場合、インスタンスメソッド-changeColorToRed:green:blue:は内部的に_i_Color_changeColorToRed_green_blueとラベル付けされている可能性があります。iインスタンスメソッドを参照し、クラスとメソッド名が追加され、コロンがアンダースコアに変更されます。パラメーターの順序はメソッド名の一部であるため、実際の名前付きパラメーターのように、コーディングスタイルや式に合わせて変更することはできません。

ただし、関数の内部名が直接使用されることはめったにありません。通常、メッセージは、Objective-Cランタイムライブラリで定義された関数呼び出しに変換されます。受信者のクラス(メッセージを送信するオブジェクト)は実行時まで知る必要がないため、リンク時にどのメソッドが呼び出されるかは必ずしもわかりません。

インスタンス化

Objective-Cクラスが作成されると、インスタンス化できます。これは、最初にクラスの初期化されていないインスタンス(オブジェクト)を割り当て、次にそれを初期化することによって行われます。両方の手順が完了するまで、オブジェクトは完全には機能しません。これらの手順は、初期化されていない割り当てられたオブジェクトが存在しないように(また、-init呼び出されたオブジェクトとは異なるオブジェクトを返す可能性があるため、中間結果を保持するのは賢明ではないため)、1行のコードで実行する必要があります。

デフォルトのパラメータなし初期化子を使用したインスタンス化:

MyObject * foo = [[ MyObject alloc ] init ];     

カスタム初期化子を使用したインスタンス化:

MyObject * foo = [[ MyObject alloc ] initWithString myString ];     

カスタム初期化が実行されていない場合、alloc-initメッセージの代わりに「new」メソッドを使用できることがよくあります。

MyObject * foo = [ MyObject new ];    

また、一部のクラスはクラスメソッド初期化子を実装します。のよう+newに、それらは結合+allocします-initが、とは異なり+new、自動解放されたインスタンスを返します。一部のクラスメソッド初期化子はパラメーターを取ります。

MyObject * foo = [ MyObjectオブジェクト];    
MyObject * bar = [ MyObject objectWithString @ "Wikipedia :)" ];    

allocメッセージは、オブジェクトのすべてのインスタンス変数を保持するのに十分なメモリを割り当て、すべてのインスタンス変数をゼロ値に設定し、メモリをクラスのインスタンスに変換します。初期化中のどの時点でも、メモリはスーパークラスのインスタンスではありません。

initメッセージは、作成時にインスタンスのセットアップを実行します。initメソッドは、多くの場合、次のように記述されます。

-  id init { 
    self = [ super init ];   
    if self {  
        //ここでオブジェクトの初期化を実行します
}    
    自己を返す; 
}

id上記の例では、リターンタイプに注意してください。このタイプは、Objective-Cの「任意のオブジェクトへのポインタ」を表します(動的型付けのセクションを参照)。

初期化パターンは、initメソッドが初期化を実行する前に、オブジェクトがスーパークラスによって適切に初期化されることを保証するために使用されます。次のアクションを実行します。

  1. self = [スーパー初期化]
    スーパークラスインスタンスにinitメッセージを送信し、結果をself(現在のオブジェクトへのポインター)に割り当てます。
  2. if(自己)
    初期化を実行する前に、返されたオブジェクトポインタが有効かどうかを確認します。
  3. 自分を返す
    selfの値を呼び出し元に返します。

無効なオブジェクトポインタの値はnilです。「if」のような条件文はnilをnullポインターのように扱うため、[super init]がnilを返した場合、初期化コードは実行されません。初期化でエラーが発生した場合、initメソッドは、「リリース」メッセージを自分自身に送信するなど、必要なクリーンアップを実行し、初期化が失敗したことを示すためにnilを返す必要があります。このようなエラーのチェックは、オブジェクトの破棄が正しく行われることを確認するために、スーパークラスの初期化を呼び出した後にのみ実行する必要があります。

クラスに複数の初期化メソッドがある場合、そのうちの1つ(「指定された初期化子」)のみがこのパターンに従う必要があります。他の人は、スーパークラスの初期化子の代わりに指定された初期化子を呼び出す必要があります。

プロトコル

他のプログラミング言語では、これらは「インターフェース」と呼ばれます。

Objective-CはNeXTで拡張され、プロトコルの導入を通じて、仕様の多重継承の概念を導入しましたが、実装は導入していませんこれは、 C ++の抽象複数継承基本クラスとして、または「インターフェース」(JavaおよびC#の場合のように)として実現可能なパターンです。Objective-Cは、非公式プロトコルと呼ばれるアドホックプロトコルと、公式プロトコルと呼ばれるコンパイラ強制プロトコルを利用します

非公式プロトコルは、クラスが実装することを選択できるメソッドのリストです。言語には存在しないため、ドキュメントで指定されています。非公式プロトコルはNSObjectのカテゴリ(以下を参照)として実装され、多くの場合、オプションのメソッドが含まれています。これらのメソッドは、実装されている場合、クラスの動作を変更できます。たとえば、テキストフィールドクラスには、ユーザーが入力したテキストのオートコンプリートを実行するためのオプションのメソッドを使用して非公式のプロトコルを実装するデリゲートがある場合があります。テキストフィールドは、デリゲートが(リフレクションを介して)そのメソッドを実装しているかどうかを検出し、実装している場合は、オートコンプリート機能をサポートするためにデリゲートのメソッドを呼び出します。

正式なプロトコルは、Java、C#、およびAda2005のインターフェイスに似ていますこれは、任意のクラスが自分自身を実装するように宣言できるメソッドのリストです。2.0より前のバージョンのObjective-Cでは、クラスがそれ自体を採用すると宣言するプロトコルにすべてのメソッドを実装する必要がありました。クラスが宣言されたプロトコルのすべてのメソッドを実装していない場合、コンパイラはエラーを発行します。Objective-C 2.0は、プロトコル内の特定のメソッドをオプションとしてマークするためのサポートを追加しました。コンパイラーは、オプションのメソッドの実装を強制しません。

クラスは、それに準拠していると言われるプロトコルを実装するように宣言する必要があります。これは実行時に検出可能です。正式なプロトコルは実装を提供できません。プロトコルに準拠するクラスが実装を提供することを呼び出し元に保証するだけです。NeXT / Appleライブラリでは、リモートシステムで実行されるオブジェクトの機能を表すために、分散オブジェクトシステムでプロトコルが頻繁に使用されます。

構文

@protocol  NSLocking- 
void lock ; _ 
-  void ロック解除;
@終わり

ロックの抽象的な考え方があることを示します。プロトコルが実装されていることをクラス定義に記載することにより、

@interface  NSLock  :NSObject < NSLocking > 
// ... 
@end

NSLockのインスタンスは、2つのインスタンスメソッドの実装を提供すると主張しています。

動的型付け

Objective-Cは、Smalltalkと同様に、動的型付けを使用できます。オブジェクトには、そのインターフェイスで指定されていないメッセージを送信できます。これにより、オブジェクトがメッセージを「キャプチャ」して、メッセージに適切に応答できる別のオブジェクトにメッセージを送信したり、同様に別のオブジェクトにメッセージを送信したりできるため、柔軟性が向上します。この動作は、メッセージ転送または委任として知られています(以下を参照)。または、メッセージを転送できない場合に備えて、エラーハンドラを使用することもできます。オブジェクトがメッセージを転送したり、応答したり、エラーを処理したりしない場合、システムは実行時例外を生成します。[24] メッセージがnilに送信される場合(nullオブジェクトポインタ)、コンパイラオプションに応じて、サイレントに無視されるか、一般的な例外が発生します。

静的型付け情報は、オプションで変数に追加することもできます。この情報は、コンパイル時にチェックされます。次の4つのステートメントでは、ますます具体的なタイプ情報が提供されます。ステートメントは実行時に同等ですが、追加情報により、渡された引数が指定されたタイプと一致しない場合にコンパイラーがプログラマーに警告することができます。

-  void setMyValue:id foo ;

上記のステートメントでは、fooはどのクラスでもかまいません。

-  void setMyValue:id < NSCopying > foo ;

上記のステートメントでは、fooNSCopyingはプロトコル に準拠する任意のクラスのインスタンスである可能性があります。

-  void setMyValue:NSNumber * foo ; 

上記のステートメントでは、fooはNSNumberクラス のインスタンスである必要があります。

-  void setMyValue:NSNumber < NSCopying > * foo ; 

上記のステートメントでは、fooはNSNumberクラスのインスタンスである必要があり、NSCopyingプロトコルに準拠している必要があります。

Objective-Cでは、すべてのオブジェクトがポインターとして表され、静的な初期化は許可されていません。最も単純なオブジェクトは、idobjc_obj *)が指す型であり、そのクラスを記述するisaポインターのみがあります。値や構造体など、Cの他のタイプは、オブジェクトシステムの一部ではないため、変更されていません。この決定は、構造体とクラスが統合されているC ++オブジェクトモデルとは異なります。

転送

Objective-Cは、応答しない可能性のあるオブジェクトへのメッセージの送信を許可します。オブジェクトは、応答したり、単にメッセージをドロップしたりするのではなく、応答できるオブジェクトにメッセージを転送できます。転送を使用すると、オブザーバーパターンプロキシパターンなどの特定のデザインパターンの実装を簡素化できます。

Objective-Cランタイムは、オブジェクトのメソッドのペアを指定します

  • 転送方法:
    -  retval_t forward:SEL sel args:arglist_t args ; // GCCを使用- id forward:SEL sel args:marg_list args ; // NeXT / Appleシステムを使用  
       
    
  • アクションメソッド:
    -  retval_t performv:SEL sel args:arglist_t args ; // GCCを使用- id performv:SEL sel args:marg_list args ; // NeXT / Appleシステムを使用  
       
    

転送を実装したいオブジェクトは、転送動作を定義するために、転送メソッドを新しいメソッドでオーバーライドするだけで済みます。アクションメソッドperformv ::は、セレクターと引数に基づいてアクションを実行するだけなので、オーバーライドする必要はありません。Objective-Cのメッセージのタイプであるタイプに 注意してください。SEL

注:Objective-Cの一般的に使用されるフレームワークであるOpenStep、Cocoa、およびGNUstepでは、Objectクラスを使用しません。-(void)forwardInvocation:(NSInvocation *)NSObjectクラスのanInvocationメソッドは、転送を行うために使用され ます

これは、転送の基本を示すプログラムの例です。

Forwarder.h
#import <objc / Object.h>

@interface  Forwarder  :オブジェクト {
  id受信者; //メッセージの転送先のオブジェクト。}  


//アクセサメソッド。
-  id 受信者;
-  id setRecipient:id _recipient ;
@終わり
Forwarder.m
#import "Forwarder.h"

@implementation フォワーダー
-  retval_t forward:SEL sel args:arglist_t args {  
  / **
  受信者が実際にメッセージに応答するかどうかを確認します。
  *これは望ましい場合と望ましくない場合があります。たとえば、受信者
  が*メッセージに応答しない場合、 
  *それ自体が転送を行う可能性があります。
  * /
  if ([受信者respondsToSelector sel ]){   
    return [受信者performv sel args args ];   
  } else {  
    return [自己エラー"受信者が応答しません" ];  
  }
}

-  id setRecipient:id _recipient { 
  [受信者の自動リリース]; 
  受信者= [ _受信者保持];   
  自己を返す; 
}

-  id 受信者{ 
  受信者を返す; 
}
@終わり
Recipient.h
#import <objc / Object.h>

//単純なRecipientオブジェクト。
@interface 受信者 :オブジェクト
-  id hello ;
@終わり
Recipient.m
#import "Recipient.h"

@implementation  Recipient

-  id hello { 
  printf "受信者はこんにちは!\ n " );

  自己を返す; 
}

@終わり
main.m
#import "Forwarder.h" 
#import "Recipient.h"

int main void {  
  フォワーダー*フォワーダー= [フォワーダー新規];    
  受信者*受信者= [受信者新規];    

  [フォワーダーsetRecipient 受信者]; //受信者を設定します。/ *   *フォワーダーがhelloメッセージに応答しないことを確認してください!  *転送されます。認識されないすべてのメソッドは、  *受信者  *に転送されます(受信者がフォワーダーに記述されているように、それらに応答した場合)  * /  
  





  [フォワーダーこんにちは]; 

  [受信者リリース]; 
  [フォワーダーリリース]; 

  0を返す; 
}

メモ

gccを使用してコンパイルすると、コンパイラは次のように報告します。

$ gcc -x Objective-c -Wno-import Forwarder.m Recipient.m main.m -lobjc
main.m:関数 `main '内:
main.m:12:警告: `Forwarder 'は` hello'に応答しません
$

コンパイラーは、 Forwarderがhelloメッセージに応答しないという以前の指摘を報告しています。この状況では、転送が実装されているため、警告を無視しても安全です。プログラムを実行すると、次の出力が生成されます。

$ ./a.out
受信者はこんにちは!

カテゴリ

Objective-Cの設計中、主な懸念事項の1つは、大規模なコードベースの保守性でした。構造化プログラミングの世界での経験から、コードを改善する主な方法の1つは、コードを細かく分割することでした。Objective-Cは、このプロセスを支援するために、Smalltalkの実装からカテゴリの概念を借用して拡張しました。[25]

さらに、カテゴリ内のメソッドは実行時にクラスに追加されます。したがって、カテゴリを使用すると、プログラマは既存のクラス(オープンクラス)にメソッドを追加できます。そのクラスを再コンパイルしたり、ソースコードにアクセスしたりする必要はありません。たとえば、システムのString実装にスペルチェッカーが含まれていない場合、Stringソースコードを変更せずに追加できます。

プログラムの実行時に、カテゴリ内のメソッドはクラス内のメソッドと区別できなくなります。カテゴリは、プライベート変数を含む、クラス内のすべてのインスタンス変数に完全にアクセスできます。

カテゴリがクラス内の既存のメソッドと同じメソッドシグネチャを持つメソッドを宣言する場合、そのカテゴリのメソッドが採用されます。したがって、カテゴリはクラスにメソッドを追加するだけでなく、既存のメソッドを置き換えることもできます。この機能を使用して、メソッドを書き直して他のクラスのバグを修正したり、プログラム内のクラスの動作にグローバルな変更を加えたりすることができます。2つのカテゴリに同じ名前のメソッドがあり、メソッドシグネチャが異なる場合、どちらのカテゴリのメソッドが採用されるかは定義されていません。

他の言語では、さまざまな方法でこの機能を追加しようとしています。TOMはObjective-Cシステムをさらに一歩進め、変数の追加も可能にしました。他の言語では、代わりにプロトタイプベースのソリューションが使用されていますが、最も注目すべきはSelfです。

C#言語とVisual Basic.NET言語は、拡張メソッドの形式で表面的には同様の機能を実装していますが、これらはクラスのプライベート変数へのアクセスを欠いています。[26] Rubyや他のいくつかの動的プログラミング言語では、この手法を「モンキーパッチ」と呼んでいます。

Logtalkは、Objective-Cカテゴリの機能を含むカテゴリの概念を(ファーストクラスのエンティティとして)実装します(Logtalkカテゴリは、新しいクラスやプロトタイプを定義するときに、きめ細かい構成単位としても使用できます。特に、Logtalkカテゴリは次のようになります。任意の数のクラスとプロトタイプによって仮想的にインポートされます)。

カテゴリの使用例

この例では、アクセサメソッドのみが実装された基本クラスを最初に定義し、基本クラスを拡張するArithmeticDisplayの2つのカテゴリを追加することにより、 Integerクラスを構築します。カテゴリは基本クラスのプライベートデータメンバーにアクセスできますが、アクセサメソッドを介してこれらのプライベートデータメンバーにアクセスすることをお勧めします。これにより、カテゴリを基本クラスからより独立させることができます。このようなアクセサーの実装は、カテゴリーの典型的な使用法の1つです。もう1つは、カテゴリを使用してメソッドを基本クラスに追加することです。ただし、モンキーパッチとも呼ばれるサブクラスのオーバーライドにカテゴリを使用することは良い習慣とは見なされていません。非公式プロトコルは、基本NSObjectクラスのカテゴリとして実装されます。慣例により、基本クラスを拡張するカテゴリを含むファイルには、BaseClass + ExtensionClass.hという名前が付けられます。

Integer.h
#import <objc / Object.h>

@interface 整数 :オブジェクト {
  int整数; 
}

-  int 整数;
-  id integer:int _integer ;
@終わり
Integer.m
#import "Integer.h"

@implementation 整数
-  int  整数{ 
  整数を返す; 
}

-  id  integer:int _integer {   
  整数= _integer ;  
  自己を返す; 
}
@終わり
整数+算術.h
#import "Integer.h"

@interface 整数 (算術)
-  id  add :(整数* addend ;   
-  id  sub :(整数* 減数;   
@終わり
整数+算術.m
#import "Integer + Arithmetic.h"

@implementation  Integer  (算術)
-  id  add :(整数* addend {    
  return [ self integer [ self integer ] + [ addend integer ]];       
}

-  id  sub :(整数* 減数{    
  return [自己整数[自己整数] - [減数整数]];       
}
@終わり
Integer + Display.h
#import "Integer.h"

@interface 整数 (表示)
-  id  showstars ;
-  id  showint ;
@終わり
Integer + Display.m
#import "Integer + Display.h"

@implementation 整数 (表示)
-  id  showstars { 
  int i x = [自己整数];     
  for i = 0 ; i < x ; i ++ {        
    printf "*" );
  }
  printf " \ n " );

  自己を返す; 
}

-  id  showint { 
  printf "%d \ n " [自己整数]);  

  自己を返す; 
}
@終わり
main.m
#import "Integer.h" 
#import "Integer + Arithmetic.h" 
#import "Integer + Display.h"

int main void {  
  整数* num1 = [整数new ]、* num2 = [整数new ];        
  int x ; 

  printf "整数を入力してください:" );
  scanf "%d" x ); 

  [ num1 integer x ]; 
  [ num1ショーター]; 

  printf "整数を入力してください:" );
  scanf "%d" x ); 

  [ num2 integer x ]; 
  [ num2showstars ] ; 

  [ num1 add num2 ]; 
  [ num1 showint ]; 

  0を返す; 
}

メモ

コンパイルは、たとえば、次のように実行されます。

gcc -x Objective-c main.m Integer.m Integer + Arithmetic.m Integer + Display.m -lobjc

#import "Integer + Arithmetic.h"[num1add:num2]の行を省略し、コンパイルでInteger + Arithmetic.mを省略することで実験できます。プログラムは引き続き実行されます。これは、必要に応じて、追加されたカテゴリを組み合わせて使用​​できることを意味します。カテゴリに何らかの能力が必要ない場合は、単にコンパイルすることはできません。

ポーズ

Objective-Cは、クラスがプログラム内の別のクラスを完全に置き換えることを許可します。置換するクラスは、ターゲットクラスを「装う」と言われます。

クラスポーズはMacOS X v10.5で非推奨と宣言されており、64ビットランタイムでは使用できません。同様の機能は、あるメソッドの実装を同じ署名を持つ別のメソッドと交換する、カテゴリ内のメソッドスウィズリングを使用することで実現できます。

まだポーズをサポートしているバージョンの場合、ターゲットクラスに送信されたすべてのメッセージは、代わりにポーズクラスによって受信されます。いくつかの制限があります。

  • クラスは、その直接または間接のスーパークラスの1つとしてのみポーズをとることができます。
  • ポーズをとるクラスは、ターゲットクラスに存在しない新しいインスタンス変数を定義してはなりません(ただし、メソッドを定義またはオーバーライドする場合があります)。
  • ターゲットクラスは、ポーズをとる前にメッセージを受信して​​いない可能性があります。

カテゴリと同様に、ポーズをとることで、既存のクラスをグローバルに拡張できます。ポーズをとると、カテゴリにない2つの機能が許可されます。

  • ポーズをとるクラスは、superを介してオーバーライドされたメソッドを呼び出すことができるため、ターゲットクラスの実装を組み込むことができます。
  • ポーズをとるクラスは、カテゴリで定義されたメソッドをオーバーライドできます。

例えば、

@interface  CustomNSApplication  :NSApplication
@終わり

@implementation  CustomNSApplication
-  void  setMainMenu:NSMenu * menu {   
  //メニューで何かをする
}
@終わり

class_poseAs ([ CustomNSApplicationクラス]、[ NSApplicationクラス]);    

これは、NSApplicationへのsetMainMenuのすべての呼び出しをインターセプトします。

#import

C言語では、#includeプリコンパイルディレクティブにより、常にファイルの内容がその時点でソースに挿入されます。Objective-Cには、#import各ファイルがコンパイル単位ごとに1回だけインクルードされることを除いて同等のディレクティブがあり、インクルードガードの必要がありません。

Linuxgccコンパイル

//ファイル:hello.m 
#import <Foundation / Foundation.h> 
int main int argc const char * argv [])       
{{
    / * Objective-Cでの私の最初のプログラム* /
    NSLog @ "Hello、World!\ n " );
    0を返す; 
}
#gccおよびMinGWコンパイラのコマンドラインをコンパイルします: 
$ gcc \ 
    $( gnustep-config --objc-flags  \ 
    -o hello \ 
    hello.m \ 
    -L / GNUstep / System / Library / Libraries \ 
    -lobjc \
    -lgnustep-base

$ ./hello

その他の機能

Objective-Cの機能により、プログラミングの問題に対する柔軟で簡単なソリューションが可能になることがよくあります。

  • 他のオブジェクトへのメソッドの委任とリモート呼び出しは、カテゴリとメッセージ転送を使用して簡単に実装できます。
  • isaポインターをスウィズリングすると、実行時にクラスを変更できます。通常、解放されたオブジェクトがゾンビオブジェクトにスウィズルされるデバッグに使用されます。ゾンビオブジェクトの唯一の目的は、誰かがそれらを呼び出したときにエラーを報告することです。Swizzlingは、データベース障害を作成するためにEnterprise ObjectsFrameworkでも使用されました。[要出典] Swizzlingは、今日、AppleのFoundation Frameworkによって、Key- ValueObservingを実装するために使用されています。

言語バリアント

目的-C ++

Objective-C ++は、 GNUコンパイラコレクションClangのフロントエンドで受け入れられている言語バリアントであり、C ++とObjective-Cの構文の組み合わせを使用するソースファイルをコンパイルできます。Objective-C ++はObjective-CがCに追加する拡張機能をC ++に追加します。さまざまな言語機能の背後にあるセマンティクスを統一するために何も行われないため、特定の制限が適用されます。

  • C ++クラスはObjective-Cクラスから派生することはできず、その逆も同様です。
  • C ++名前空間は、Objective-C宣言内で宣言することはできません。
  • Objective-C宣言は、C ++名前空間内ではなく、グローバルスコープにのみ表示される場合があります
  • Objective-Cクラスは、デフォルトのコンストラクターがない、または1つ以上の仮想メソッドを持つC ++クラスのインスタンス変数を持つことはできません[引用が必要]が、C ++オブジェクトへのポインターは、制限なしでインスタンス変数として使用できます(-にnewを割り当てます)。 initメソッド)。
  • C ++の「値による」セマンティクスは、ポインタを介してのみアクセスできるObjective-Cオブジェクトには適用できません。
  • Objective-C宣言をC ++テンプレート宣言内に含めることはできません。その逆も同様です。ただし、Objective-Cタイプ(例Classname *)は、C ++テンプレートパラメーターとして使用できます。
  • Objective-CとC ++の例外処理は異なります。それぞれのハンドラーは、他のタイプの例外を処理できません。その結果、オブジェクトデストラクタは実行されません。これは、最近の「Objective-C 2.0」ランタイムでは、Objective-C例外が完全にC ++例外に置き換えられるか(Appleランタイム)、またはObjective-C ++ライブラリがリンクされている場合(GNUstep libobjc2)に部分的に置き換えられるため、軽減されます。[27]
  • Objective-CブロックとC ++ 11ラムダは別個のエンティティです。ただし、ブロックが予期される場所にラムダを渡すと、macOSでブロックが透過的に生成されます。[28]

Objective-C 2.0

2006年のWorldwideDevelopers Conferenceで、Appleは「Objective-C2.0」のリリースを発表しました。これは、「最新のガベージコレクション、構文の強化、[29]ランタイムパフォーマンスの改善、[30]および64 」を含むObjective-C言語の改訂版です。ビットサポート」。2007年10月にリリースされたMacOS X v10.5には、Objective-C2.0コンパイラが含まれていました。GCC 4.6は、宣言および合成されたプロパティ、ドット構文、高速列挙、オプションのプロトコルメソッド、メソッド/プロトコル/クラス属性、クラス拡張、新しいGNU Objective-CランタイムAPIなど、多くの新しいObjective-C機能をサポートします。[31]

NeXTの最後のObjective-Cバージョンは「objc4」であったため、Objective-C 2.0という名前は、言語のバージョン管理システムの中断を表しています。[32]このプロジェクト名は、Mac OS X Leopard(10.5)のレガシーObjective-Cランタイムソースコードの最後のリリースで保持されていました。[33]

ガベージコレクション

Objective-C 2.0は、オプションの保守的な世代別ガベージコレクターを提供しました。下位互換モードで実行すると、ランタイムは保持」や「解放」などの参照カウント操作を操作なしに変換しました。ガベージコレクションが有効になっている場合、すべてのオブジェクトがガベージコレクションの対象になりました。通常のCポインターは、「__ strong」で修飾して、基になる書き込みバリアコンパイラーインターセプトをトリガーし、ガベージコレクションに参加させることができます。[34]オブジェクト(またはより単純に、GCメモリ)が収集されるときに「__weak」とマークされたポインタがゼロに設定されるように、ゼロ化の弱いサブシステムも提供されました。ガベージコレクターは、Objective-C2のiOS実装には存在しません。[35] Objective-Cのガベージコレクションは、優先度の低いバックグラウンドスレッドで実行され、ユーザーエクスペリエンスの応答性を維持する目的で、ユーザーイベントで停止できます。[36]

ガベージコレクションは、自動参照カウント(ARC)を優先して、Mac OS Xv10.8で非推奨になりました。[37] ARM64で実行されているiOS7 のObjective-Cは、64ビットワードのうち19ビットを使用して、タグ付きポインターの形式として参照カウントを格納します。[38] [39]

プロパティ

Objective-C 2.0では、インスタンス変数をプロパティとして宣言するための新しい構文と、アクセサメソッドの生成を構成するためのオプションの属性が導入されています。プロパティは、ある意味でパブリックインスタンス変数です。つまり、インスタンス変数をプロパティとして宣言すると、外部クラスにそのプロパティへのアクセス(場合によっては制限されている、たとえば読み取り専用)が提供されます。プロパティは「読み取り専用」として宣言でき、、、などのストレージセマンティクスを提供assignできcopyますretainデフォルトでは、プロパティが考慮されatomic、複数のスレッドが同時にそれらにアクセスすることを防ぐロックが発生します。プロパティは、として宣言できますnonatomic。これにより、このロックが削除されます。

@interface  Person  :NSObject  {
@公衆
  NSString *名前; 
@プライベート
  int年齢; 
}

@property copy NSString * name ;  
@property 読み取り専用int age ;  

-  id initWithAge:int age ;
@終わり

@synthesizeプロパティは、プロパティ宣言に従ってgetter(および読み取り専用でない場合はsetter)メソッドを生成するキーワードを使用して実装されます。または、getterメソッドとsetterメソッドを明示的に実装する必要があります。または、@dynamicキーワードを使用して、アクセサーメソッドが他の手段で提供されることを示すことができます。clang 3.1以降を使用してコンパイルすると、明示的に宣言されていない@dynamic、マークされている、readonlyまたは完全なユーザー実装のgetterおよびsetterを持つすべてのプロパティは、自動的に暗黙的に@synthesize'dされます。

@implementation  Person
@synthesize name ; 

-  id initWithAge:int initAge { 
  self = [ super init ];   
  if self {  
    //注:プロパティセッターではなく、インスタンス変数の直接割り当て
age = initAge ;      
  }
  自己を返す; 
}

-  int 年齢{ 
  帰国年齢; 
}
@終わり

プロパティには、従来のメッセージパッシング構文、ドット表記、またはKey-Valueコーディングでは、「valueForKey:」/「setValue:forKey:」メソッドを介した名前でアクセスできます。

Person * aPerson = [[ Person alloc ] initWithAge 53 ];     
aPerson name = @ "Steve" ; //注:ドット表記、合成セッターを使用、// [aPerson setName:@ "Steve"]と同等; NSLog @ "メッセージによるアクセス(%@)、ドット表記(%@)、プロパティ名(%@)および"   
                         

       "直接インスタンス変数アクセス(%@)" 
              [人名]  
      aPerson name [ aPerson valueForKey @ "name" ]、aPerson- > name );     

ドット表記を使用してインスタンスメソッド内でプロパティアクセサーを呼び出すには、「self」キーワードを使用する必要があります。

-  void introduceMyselfWithProperties:BOOL useGetter { 
  NSLog @ "こんにちは、私の名前は%@です。" useGetter self .name name );     
  //注:getterとivarのアクセス
}

クラスまたはプロトコルのプロパティは、動的にイントロスペクトされる場合があります。

int i ; 
int propertyCount = 0 ;   
objc_property_t * propertyList =  
    class_copyPropertyList ([ aPerson class ]、propertyCount );  

for i = 0 ; i < propertyCount ; i ++ {        
  objc_property_t * thisProperty = propertyList + i ;     
  const char * propertyName = property_getName * thisProperty );    
  NSLog @ "Personにはプロパティがあります: '%s'" propertyName ); 
}

壊れにくいインスタンス変数

Objective-C 2.0は、ランタイムでサポートされている場合(つまり、64ビットmacOSおよびすべてのiOSのコードをビルドする場合)に脆弱でないインスタンス変数を提供します。最新のランタイムでは、インスタンス変数アクセスに間接層が追加され、ダイナミックリンカーが実行時にインスタンスレイアウトを調整できるようになります。この機能により、Objective-Cコードに2つの重要な改善が可能になります。

  • 壊れやすいバイナリインターフェイスの問題を排除します; スーパークラスは、バイナリ互換性に影響を与えることなくサイズを変更できます。
  • これにより、プロパティのバッキングを提供するインスタンス変数を、クラスのインターフェイスで宣言せずに実行時に合成できます。

高速列挙

NSEnumeratorオブジェクトまたはインデックスを使用してコレクションを反復処理する代わりに、Objective-C2.0は高速な列挙構文を提供します。Objective-C 2.0では、次のループは機能的に同等ですが、パフォーマンス特性が異なります。

// NSEnumeratorの使用
NSEnumerator * enumerator = [ thePeople objectEnumerator ];    
* p ; 

while ((p = [列挙子nextObject ])!= nil {       
  NSLog @ "%@は%i歳です。" [ p name ]、[ p age ]);    
}
//インデックス
を使用するint i = 0 ; i < [ thePeople count ]; i ++ {          
  Person * p = [ thePeople objectAtIndex i ];    
  NSLog @ "%@は%i歳です。" [ p name ]、[ p age ]);    
}
//高速列挙
を使用してPerson * p in thePeople {     
  NSLog @ "%@は%i歳です。" [ p name ]、[ p age ]);    
}

オブジェクトを列挙するためのメソッド呼び出しは、NSFastEnumerationプロトコルを使用したポインター演算に置き換えられるため、高速列挙は標準の列挙よりも効率的なコードを生成します。[40]

クラス拡張

クラス拡張は、カテゴリ名のないカテゴリ宣言と同じ構文を持ち、そこで宣言されたメソッドとプロパティはメインクラスに直接追加されます。これは主に、パブリックヘッダーにメソッドをアドバタイズせずにクラスにメソッドを追加するためのカテゴリの代替として使用されます。クラス拡張の場合、コンパイラは、プライベートに宣言されたすべてのメソッドが実際に実装されていることを確認します。[41]

ココア開発への影響

上記のObjective-C2.0の改善を利用するmacOS用に開発されたすべてのObjective-Cアプリケーションは、10.5(Leopard)より前のすべてのオペレーティングシステムと互換性がありません。高速列挙は標準の列挙とまったく同じバイナリを生成しないため、高速列挙を使用すると、Mac OSXバージョン10.4以前でアプリケーションがクラッシュします。

ブロック

ブロックは、Objective-C(およびCC ++ )の非標準の拡張機能であり、特別な構文を使用してクロージャを作成します。ブロックは、Mac OS X 10.6 "Snow Leopard"以降、iOS 4以降、およびlibobjc2 1.7を使用し、clang3.1以降でコンパイルするGNUstepでのみサポートされます。[42]

#include <stdio.h> 
#include <Block.h> 
typedef int ^ IntBlock )();  

IntBlock MakeCounter int start int増分{     
  __block int i = start ;    

  Block_copyを返す^ {   
    int ret = i ;   
    i + =インクリメント;  
    retを返す; 
  });

}

int main void {  
  IntBlock mycounter = MakeCounter 5、2 ; _    
  printf "最初の呼び出し:%d \ n " mycounter ()); 
  printf "2番目の呼び出し:%d \ n " mycounter ()); 
  printf "3回目の呼び出し:%d \ n " mycounter ()); 

  / *コピーされたため、リリースする必要があります* /
  Block_release mycounter );

  0を返す; 
}
/ *出力:
  最初の呼び出し:5 
  2番目の呼び出し:7 
  3番目の呼び出し:9 
* /

現代のObjective-C

Appleは、Objective2.0にいくつかの追加機能を追加してきました。追加は「 AppleLLVMコンパイラ」、つまり言語のclangフロントエンドにのみ適用されます。紛らわしいことに、Appleが使用するバージョンはLLVMアップストリームのバージョンとは異なります。オープンソースのLLVMバージョン番号への変換については、Xcode§ツールチェーンのバージョンを参照してください。[43]

自動参照カウント

retain自動参照カウント(ARC)はコンパイル時の機能であり、プログラマーがとを使用して保持カウントを手動で管理する必要がありませんrelease[44]実行時に発生するガベージコレクション とは異なり、ARCは保持カウントを管理する別のプロセスのオーバーヘッドを排除します。ARCと手動メモリ管理は相互に排他的ではありません。プログラマーは、個々のコードファイルに対してARCを無効にすることにより、ARC対応プロジェクトで非ARCコードを引き続き使用できます。Xcodeは、プロジェクトをARCに自動的にアップグレードすることもできます。

ARCはLLVM3.0で導入されました。これは、Xcode 4.2(2011)またはAppleLLVMコンパイラ3.0に変換されます。[45]

リテラル

NeXTおよびAppleObj-Cランタイムには、リテラル構文を使用して新しい文字列を作成する@"a new string"、またはCoreFoundation定数kCFBooleanTrueにドロップkCFBooleanFalseNSNumberてブール値を使用する短い形式の方法が長い間含まれています。この形式を使用すると、プログラマーはinitWithString特定の操作を行うときに、より長い方法や同様の方法を使用する必要がなくなります。

Apple LLVMコンパイラ4.0(Xcode 4.4)以降を使用する場合、配列、辞書、および数値(、、NSArrayクラス)はNSDictionaryNSNumberメソッドの代わりにリテラル構文を使用して作成することもできます。[46](Apple LLVMコンパイラ4.0は、オープンソースのLLVMおよびClang 3.1に変換されます。)[47]

リテラルのない例:

NSArray * myArray = [ NSArray arrayWithObjects object1 object2 object3 nil ];    
NSDictionary * myDictionary1 = [ NSDictionary dictionaryWithObject someObject forKey @ "key" ];     
NSDictionary * myDictionary2 = [ NSDictionary dictionaryWithObjectsAndKeys object1 key1 object2 key2 nil ];        
NSNumber * myNumber = [ NSNumber numberWithInt myInt ];    
NSNumber * mySumNumber = [ NSNumber numberWithInt :( 2 + 3 )];     
NSNumber * myBoolNumber = [ NSNumber numberWithBool YES ];    

リテラルの例:

NSArray * myArray = @ [ object1 object2 object3 ] ;       
NSDictionary * myDictionary1 = @ { @ "key" someObject } ;       
NSDictionary * myDictionary2 = @ { key1 object1 key2 object2 } ;        
NSNumber * myNumber = @(myInt ;   
NSNumber * mySumNumber = @(2 + 3 ;   
NSNumber * myBoolNumber = @YES ;   
NSNumber * myIntegerNumber = @ 8 ;   

ただし、実行可能ファイルの定数にコンパイルされる文字列リテラルとは異なり、これらのリテラルは上記のメソッド呼び出しと同等のコードにコンパイルされます。特に、手動で参照カウントされるメモリ管理では、これらのオブジェクトは自動解放されるため、たとえば関数静的変数やその他の種類のグローバルで使用する場合は、さらに注意が必要です。

添え字

Apple LLVMコンパイラ4.0以降を使用する場合、配列と辞書(NSArrayおよびNSDictionaryクラス)は添え字を使用して操作できます。[46] 添え字は、インデックス(配列)またはキー(辞書)から値を取得するために使用でき、可変オブジェクトでは、オブジェクトをインデックスまたはキーに設定するためにも使用できます。コードでは、添え字は角かっこを使用して表されます[ ][48]

添え字なしの例:

id object1 = [ someArray objectAtIndex 0 ];    
id object2 = [ someDictionary objectForKey @ "key" ];    
[ someMutableArray replaceObjectAtIndex 0 withObject object3 ];  
[ someMutableDictionary setObject object4 forKey @ "key" ];  

添え字付きの例:

id object1 = someArray [ 0 ];   
id object2 = someDictionary [ @ "key" ];   
someMutableArray [ 0 ] = object3 ;  
someMutableDictionary [ @ "key" ] = object4 ;  

「モダン」Objective-C構文(1997)

AppleがNeXTを購入した後、 SmalltalkよりもJavaに精通しているプログラマーがこの言語を受け入れやすくするための試みが行われました。これらの試みの1つは、当時のObjective-Cの「モダン構文」と呼ばれていたものを導入することでした[49](現在の「クラシック」構文とは対照的)。動作に変更はありませんでした。これは単なる代替構文でした。次のようなメソッド呼び出しを作成する代わりに

    object = [[ MyClass alloc ] init ];    
    [オブジェクトfirstLabel param1 secondLabel param2 ];    

代わりに次のように書かれました

    object = MyClass .alloc init ;  
    オブジェクトラベルparam1 param2 );    

同様に、宣言はフォームから行われました

    - void firstLabel int param1 secondLabel int param2 ;    

    - void ラベルint param1 int param2 );       

この「最新の」構文は、Objective-C言語の現在の方言ではサポートされなくなりました。

mulle-objc

mulle-objcプロジェクトは、Objective-Cのもう1つの再実装です。バックエンドとしてGCCまたはClang / LLVMコンパイラをサポートします。構文、セマンティクス、およびABIの互換性の点で、他のランタイムとは異なります。Linux、FreeBSD、およびWindowsをサポートします。

ポータブルオブジェクトコンパイラ

元のStepstone実装にいくつかの拡張機能を追加しGCC / NeXT / Apple実装に加えて、Portable ObjectCompilerと呼ばれる別の無料のオープンソースObjective-C実装も存在します。[50] Portable ObjectCompilerによって実装される拡張機能のセットはGCC / NeXT / Appleの実装とは異なります。特に、 Objective-C用のSmalltalkのようなブロックが含まれていますが、プロトコルとカテゴリがなく、OpenStepとその派生物および親戚で広く使用されている2つの機能があります。全体として、POCは、言語の進化におけるNeXT以前の古い段階を表しており、BradCoxの1991年の本にほぼ準拠しています。

また、ObjectPakと呼ばれるランタイムライブラリも含まれています。これは、Coxの元のICPak101ライブラリ(Smalltalk-80クラスライブラリから派生)に基づいており、OpenStepFoundationKitとはまったく異なります。

GEOS Objective-C

PC GEOSシステムは、GEOSObjective -Cまたはgocとして知られるプログラミング言語を使用しました[51]名前の類似性にもかかわらず、2つの言語は、全体的な概念と@記号で始まるキーワードの使用においてのみ類似しています。

Clang

LLVMプロジェクトの一部であるClangコンパイラスイートは、Objective-Cおよびその他の言語を実装しています。GCC 4.3(2008)がGPLv3に切り替わった後、Appleはclangを支持してそれを放棄しました。これは、変更する法的権限がより高いコンパイラです。その結果、最新のObjective-C言語機能の多くは、Clangでのみサポートされています。

clangベースの「LLVMコンパイラ」に対するAppleのバージョン管理スキームは、LLVMのオープンソースバージョン管理とは異なります。翻訳については、Xcode§ツールチェーンのバージョンを参照してください[43]

GNU、GNUstep、およびWinObjC

GNUプロジェクトは長い間、NeXTおよびObj-Cプログラムを移植するためのプラットフォームに関心を持ってきました。GCCのlibobjcディレクトリのChangeLogは、それが1998年より前に存在していたことを示唆しており(GCC 2.95)、そのREADMEは1993年の書き換え(GCC 2.4)をさらに示しています。[52]

NeXTフロントエンドのソースコードは、GCCの一部として作成されたためにリリースされ、派生物を作成する人にそうするように強制するGNU PublicLicenseをリリースしました。[いつ?] Appleは、GCCのフォークを4.2.1までリリースするというこの伝統を継続し、その後、コンパイラを放棄しました。GCCのメンテナは変更を取り入れましたが、Objective-C2.0言語などの新しい機能のサポートにはあまり投資しませんでした。[32] :どのコンパイラ 

新しい言語に興味を持っているGNUstep開発者は、 2009年にlibobjc2と呼ばれるGCCから独立したプロジェクトにGCC libobjcをフォークしました。また、新しい言語構文を利用するためにランタイムをClangで使用するように手配しました。[32] :どのコンパイラ GCCが同時にゆっくりと移動しましたが、GCC 4.6.0(2011)では、libobjcでもObjective-C2.0に移行しました。[31] [53] GNUstepのドキュメントによると、GCCの実装には、ブロック、脆弱でない変数、および新しいARCのサポートがまだありません。[32] :どのランタイム 

Microsoftは、2015年にlibobjc2をユニバーサルWindowsプラットフォーム用のiOSブリッジであるWinObjCの一部にフォークしました。CocoaTouchと基盤となるAPIの独自の実装と組み合わせることで、プロジェクトはUWPアプリ内でiOSアプリケーションコードを再利用できます。[54]

Windowsでは、Objective-C開発ツールがGNUStepのWebサイトからダウンロードできるように提供されています。GNUStep開発システムは次のパッケージで構成されています:GNUstep MSYSシステム、GNUstepコア、GNUstep Devel、GNUstep Cairo、ProjectCenter IDE(Xcodeに似ていますが、それほど複雑ではありません)、Gorm(Xcode NIBビルダーに似たインターフェイスビルダー)。これらのバイナリインストーラーは2016年以降更新されていないため[55] 、代わりにCygwinまたはMSYS2でビルドしてインストールすることをお勧めします。

ライブラリ使用

今日のObjective-Cは、 CocoaGNUstepObjFWなどの標準オブジェクトの固定ライブラリ(「キット」または「フレームワーク」と呼ばれることが多い)と組み合わせて使用​​されることがよくありますこれらのライブラリには多くの場合オペレーティングシステムが付属しています。GNUstepライブラリには多くの場合Linuxが付属していますベースのディストリビューションとCocoaにはmacOSが付属しています。プログラマーは、既存の基本クラス(NSObject / OFObject)から機能を継承する必要はありません。Objective-Cでは、既存の機能を継承しない新しいルートクラスを宣言できます。もともと、Objective-Cベースのプログラミング環境は通常、他のほとんどすべてのクラスが継承する基本クラスとしてObjectクラスを提供していました。OpenStepの導入により、NeXTはNSObjectという名前の新しい基本クラスを作成しました。これは、Objectに追加機能を提供します(たとえば、rawポインターの代わりにオブジェクト参照と参照カウントを使用することに重点を置いています)。CocoaのほとんどすべてのクラスはNSObjectを継承しています。

名前の変更は、OpenStep API内のクラスの新しいデフォルトの動作を区別するのに役立つだけでなく、Object(NeXTSTEP(および多かれ少なかれ他のObjective-Cクラスライブラリ)で使用される元の基本クラス)を使用するコードを許可しました。 NSObjectを使用したコードと同じランタイムで共存します(いくつかの制限があります)。2文字のプレフィックスの導入も、Objective-Cにはない単純な形式の名前空間になりました。プレフィックスを使用して非公式のパッケージ識別子を作成することは、Objective-Cコミュニティの非公式のコーディング標準となり、今日まで続いています。

最近では、パッケージマネージャーとパッケージのリポジトリの両方を目的としたCocoaPodsなどのパッケージマネージャーが登場し始めています。過去数年間に作成された多くのオープンソースのObjective-Cコードは、CocoaPodsを使用してインストールできるようになりました。

言語の分析

Objective-Cの実装では、 Cで記述されたシンランタイムシステムを使用します[要出典]。これにより、アプリケーションのサイズはほとんど追加されません。対照的に、それが作成された時点でのほとんどのオブジェクト指向システムは、大規模な仮想マシンを使用していましたランタイム。大量のメモリがあったSmalltalkシステムとは対照的に、Objective-Cで記述されたプログラムは、コードとライブラリのサイズ(通常はソフトウェアディストリビューションに含める必要はありません)よりも大きくない傾向があります。ウィンドウを開くためだけに使用されます。Objective-Cの動的型付けではメソッドを削除またはインライン化できないため、Objective-Cアプリケーションは類似のCまたはC ++アプリケーションよりも大きくなる傾向があります。プログラマーは、呼び出しを委任、転送、オンザフライでセレクターを構築し、それらをランタイムシステムに渡す自由があるため、Objective-Cコンパイラーは、未使用のメソッドを削除したり、呼び出しをインライン化したりすることが安全であるとは想定できません。

同様に、この言語は、新しいコンパイラーとしてではなく、既存のCコンパイラー(GCCでは、最初にプリプロセッサーとして、次にモジュールとして)に実装できます。これにより、Objective-CはCコード、ライブラリ、ツールなどの膨大な既存のコレクションを活用できます。既存のCライブラリをObjective-Cラッパーでラップして、オブジェクト指向スタイルのインターフェイスを提供できます。この点では、 GTKアプリケーション の開発で広く使用されているGObjectライブラリとVala言語に似ています。

これらの実際的な変更はすべて、参入障壁を低くしました。これは、1980年代にSmalltalkが広く受け入れられた最大の問題である可能性があります。

一般的な批判は、Objective-Cが名前空間の言語サポートを持っていないということです代わりに、プログラマーはクラス名にプレフィックスを追加する必要があります。これは、従来、名前空間名よりも短いため、衝突が発生しやすくなります。2007年現在、 Cocoaプログラミング環境のすべてのmacOSクラスおよび関数には、macOSまたはiOSコアに属するものとして識別するために「NS」(NSObject、NSButtonなど)のプレフィックスが付いています。「NS」は、 NeXTSTEPの開発中に定義されたクラスの名前に由来します

Objective-CはCの厳密なスーパーセットであるため、Cのプリミティブ型をファーストクラスのオブジェクトとして扱いません。

C ++とは異なり、Objective-Cは演算子のオーバーロードをサポートしていませんまた、C ++とは異なり、Objective-Cでは、オブジェクトが1つのクラスからのみ直接継承できます(多重継承は禁止されています)。ただし、ほとんどの場合、同じ結果を達成するための代替方法として、カテゴリとプロトコルを使用できます。

Objective-Cは動的ランタイム型付けを使用し、すべてのメソッド呼び出しは関数呼び出し(または場合によってはsyscall)であるため、多くの一般的なパフォーマンス最適化をObjective-Cメソッドに適用できません(例:インライン化、定数伝播、手続き間最適化、および集合体のスカラー置換)。これにより、そのような最適化が可能なC ++などの言語での同様の抽象化と比較して、Objective-C抽象化のパフォーマンスが制限されます。

メモリ管理

Objective-Cの最初のバージョンはガベージコレクションをサポートしていませんでした。当時、この決定はいくつかの議論の問題であり、多くの人々は、システム全体を使用できなくするために長い「デッドタイム」(Smalltalkが収集を実行したとき)を考慮しました。一部のサードパーティの実装ではこの機能が追加されており(特にBoehmを使用したGNUstep )、AppleはMac OS Xv10.5の時点でこの機能を実装しています。[56]ただし、macOSおよびiOSの最近のバージョンでは、ガベージコレクションは非推奨になり、2011年に導入された自動参照カウント(ARC)が採用されました。

ARCを使用すると、コンパイラは静的コード分析に基づいて、保持呼び出しと解放呼び出しをObjective-Cコードに自動的に挿入します自動化により、プログラマーはメモリ管理コードを記述する必要がなくなります。ARCは、Objective-C言語への弱参照も追加します。[57]

Objective-CとC ++の哲学的な違い

C ++とObjective-Cの設計と実装は、 Cを拡張するための根本的に異なるアプローチを表しています。

Cの手続き型プログラミングのスタイルに加えて、C ++は、特定の形式のオブジェクト指向プログラミングジェネリックプログラミング、およびメタプログラミングを直接サポートします。C ++には、いくつかのコンテナクラスを含む大規模な標準ライブラリも付属しています同様に、Objective-Cは、オブジェクト指向プログラミング動的型付け、およびリフレクションをCに追加します。Objective-C自体は標準ライブラリを提供しませんが、Objective-Cが使用されるほとんどの場所では、OpenStepのようなもので使用されます。 OPENSTEPCocoaGNUstepなどのライブラリ、C ++の標準ライブラリと同様の機能を提供します。

注目すべき違いの1つは、Objective-Cがリフレクション機能のランタイムサポートを提供するのに対し、C ++はCにランタイムサポートを少ししか追加しないことです。Objective-Cでは、オブジェクトがそれ自体のプロパティについて照会できます。あるメッセージ。C ++では、これは外部ライブラリを使用しないと不可能です。

リフレクションの使用は、言語の動的(実行時)機能と静的(コンパイル時)機能の幅広い区別の一部です。Objective-CとC ++はそれぞれ両方の機能を組み合わせて採用していますが、Objective-Cは明らかに実行時の決定を対象としており、C ++はコンパイル時の決定を対象としています。動的プログラミングと静的プログラミングの間の緊張には、プログラミングにおける古典的なトレードオフの多くが含まれます。動的機能は柔軟性を追加し、静的機能は速度と型チェックを追加します。

ジェネリックプログラミングとメタプログラミングは、ランタイムポリモーフィズムを使用して両方の言語で実装できますC ++では、これは仮想関数実行時型識別の形式を取りますが、Objective-Cは動的型付けとリフレクションを提供します。Objective-CとC ++はどちらもコンパイル時のポリモーフィズム(ジェネリック関数)をサポートしており、Objective-Cは2015年にこの機能を追加するだけです。

も参照してください

参考文献

  1. ^ 「ランタイムバージョンとプラットフォーム」Developer.apple.com2016年7月20日にオリジナルからアーカイブされました2017年12月24日取得
  2. ^ ラトナー、クリス(2014年6月3日)。「クリス・ラトナーのホームページ」クリス・ラトナー。2014年6月4日にオリジナルからアーカイブされました2014年6月3日取得Swift言語は、言語の専門家、ドキュメンテーションの達人、コンパイラ最適化の忍者、そしてアイデアの洗練とバトルテストに役立つフィードバックを提供した非常に重要な社内ドッグフーディンググループのチームによるたゆまぬ努力の産物です。もちろん、Objective-C、Rust、Haskell、Ruby、Python、C#、CLUなど、他の多くの言語からアイデアを引き出して、この分野で苦労して獲得した経験からも大きな恩恵を受けました。
  3. ^ シン、アミット(2003年12月)。「MacOSXの簡単な歴史」Mac OSXの内部。2012年5月14日にオリジナルからアーカイブされました2012年6月11日取得
  4. ^ 「アプリフレームワーク」りんご。2014年6月。2019年2月16日のオリジナルからアーカイブ2019年2月13日取得
  5. ^ ガーリング、カレブ。「iPhoneコーディング言語は今や世界で3番目に人気があります」有線2013年9月9日にオリジナルからアーカイブされました2013年5月20日取得
  6. ^ ウェントク、リチャード(2009)。Cocoa:開発者向けリファレンスApple DeveloperSeriesの第5巻ジョン・ワイリーとサンズ。ISBN 978-0-470-49589-62017年2月16日にオリジナルからアーカイブされました2016年7月22日取得
  7. ^ Biancuzzi、Federico; ウォーデン、シェーン(2009)。プログラミングの首謀者O'Reilly Media、 Inc。pp。242–246。ISBN 978-0-596-51517-12017年2月17日にオリジナルからアーカイブされました2016年7月22日取得
  8. ^ コックス、ブラッド(1983)。「オブジェクト指向プリコンパイラ:C言語でのSmalltalk80メソッドのプログラミング」ACMSIGPLANの通知ニューヨーク州ニューヨーク:ACM18(1)。土井10.1145 /948093.948095S2CID6975032 _ 2011年2月17日取得 
  9. ^ 「CommonLispとReadline」2014年9月6日にオリジナルからアーカイブされました2014年9月15日取得この問題は、NeXTが変更されたGCCを2つの部分に分けて配布し、ユーザーがそれらをリンクできるようにすることを提案したときに最初に発生しました。ジョブズは私にこれが合法かどうか尋ねました。当時の私には、あなたが使用しているもののような推論に従って、それがあったように見えました。しかし、その結果は自由ソフトウェアにとって非常に望ましくないので、私は弁護士に尋ねなければならないと言いました。弁護士の言ったことは私を驚かせた。彼は、裁判官はそのような計画を「サブターフュージ」と見なし、それらに対して非常に厳しいだろうと述べた。彼は、裁判官は、それがどのようにラベル付けされているかではなく、「本当に」1つのプログラムであるかどうかを尋ねると述べた。それで私はジョブズに戻り、彼の計画はGPLによって許可されていないと信じていると言いました。これの直接の結果は、ObjectiveCフロントエンドができたことです。
  10. ^ 「GNUstep:はじめに」GNUstep開発者/ GNUプロジェクト。2012年8月6日にオリジナルからアーカイブされました2012年7月29日取得
  11. ^ 「クレステンクラブソープ| LinkedIn」www.linkedin.com2014年7月15日にオリジナルからアーカイブされました2016年6月23日取得
  12. ^ 「Objective-Cコードを書く」apple.com。2013年4月23日。2013年12月24日のオリジナルからアーカイブ2013年12月22日取得
  13. ^ 「Objective-Cブートキャンプ」2018年2月11日にオリジナルからアーカイブされました2018年2月11日取得Objective-CはANSICの厳密なスーパーセットです
  14. ^ 「Objective-Cの調査」2014年9月4日にオリジナルからアーカイブされました2014年9月4日取得Objective-Cは、Cのオブジェクト指向の厳密なスーパーセットです。
  15. ^ リー、キース(2013年9月3日)。ProObjective-C押してください。ISBN 97814302505002018年5月14日にオリジナルからアーカイブされました2017年12月24日– Googleブックス経由で取得。
  16. ^ 「Objective-Cヘッダーのタグ」2017年4月1日にオリジナルからアーカイブされました2018年2月11日取得Objective-CはCのスーパーセットです
  17. ^ 「AppScanSource8.7が利用可能になりました」2017年2月3日にオリジナルからアーカイブされました2018年2月11日取得Objective-Cプログラミング言語はCプログラミング言語のスーパーセットです
  18. ^ Apple、Inc。(2009年10月19日)。「動的メソッド解決」Objective-Cランタイムプログラミングガイド2010年9月7日にオリジナルからアーカイブされました2014年11月25日取得
  19. ^ Apple、Inc。(2009年10月19日)。「メッセージングエラーの回避」Objective-Cプログラミング言語2010年9月8日にオリジナルからアーカイブされました。
  20. ^ "objc_msgSend-Objective-Cランタイム"Appleデベロッパドキュメント2020年2月10日取得
  21. ^ 「GNUObjective-Cランタイムを使用したメッセージング」GNUコンパイラコレクション(GCC)の使用2020年2月10日取得
  22. ^ 「カテゴリ」Apple Developer(Cocoaコアコンピテンシー)
  23. ^ ダルリンプル、マーク; Knaster、Scott(2012年6月27日)。MacでObjective-Cを学ぶp。9. ISBN 9781430241881.m拡張子は、Objective-Cが最初に導入されたとき、元々は「メッセージ」を表し、Objective-Cの中心的な機能を指していました。
  24. ^ 「Objective-Cランタイムプログラミングガイド」Apple Inc. 2014年4月4日のオリジナルからアーカイブ2013年10月21日取得
  25. ^ 「ACMSIGGRAPH1983 Issue 8-Smalltalk」2009年4月15日にオリジナルからアーカイブされました2008年10月7日取得
  26. ^ 「拡張メソッド(C#プログラミングガイド)」マイクロソフト。2010年10月。2011年7月11日のオリジナルからアーカイブ2011年7月10日取得
  27. ^ 「Objective-CでのC ++の使用」Mac OSXリファレンスライブラリ2010年9月5日にオリジナルからアーカイブされました2010年2月10日取得
  28. ^ 「Clang言語拡張機能— Clang3.5ドキュメント」Clang.llvm.org。2014年2月24日にオリジナルからアーカイブされました2014年4月16日取得
  29. ^ 「Objective-C2.0:より多くの手がかり」Lists.apple.com。2006年8月10日。2009年6月18日のオリジナルからアーカイブ2010年5月30日取得
  30. ^ 「Re:Objective-C2.0」Lists.apple.com。2010年11月24日にオリジナルからアーカイブされました2010年5月30日取得
  31. ^ a b "GCC 4.6リリースシリーズ—変更、新機能、および修正:GNUプロジェクト:フリーソフトウェアファウンデーション"Gcc.gnu.org2018年1月5日にオリジナルからアーカイブされました2017年12月24日取得
  32. ^ a b cd 「 ObjC2FAQ GNUstep 2020年1月6日取得
  33. ^ 「ソースブラウザ:objc4、756.2」Appleオープンソース2020年1月6日取得
  34. ^ ガベージコレクションプログラミングガイド: 2012年6月5日にWebCiteでアーカイブされたガベージコレクションAPI (Apple開発者のWebサイト-「__ strong」を検索)
  35. ^ 「ガベージコレクションプログラミングガイド:ガベージコレクションの概要」Apple Inc. 2011年10月3日。2012年6月5日のオリジナルからアーカイブ2011年12月23日取得
  36. ^ 「開発者のためのLeopardテクノロジーシリーズ:Objective-C2.0の概要」Apple Inc. 2007年11月6日。2010年7月24日のオリジナルからアーカイブ2010年5月30日取得
  37. ^ 「ARCリリースノートへの移行」Apple Inc. 2012年7月17日。2012年6月5日のオリジナルからアーカイブ2012年8月26日取得
  38. ^ マイクアッシュ。「金曜日のQ&A 2013-09-27:ARM64とあなた」mikeash.com。2014年4月26日にオリジナルからアーカイブされました2014年4月27日取得
  39. ^ 「HamsterEmporium:[objc Explain]:Non-pointerisa」Sealiesoftware.com。2013年9月24日。2014年6月3日のオリジナルからアーカイブ2014年4月27日取得
  40. ^ Apple、Inc。(2009)。「高速列挙」apple.com。2009年12月17日にオリジナルからアーカイブされました2009年12月31日取得
  41. ^ Free Software Foundation、Inc。(2011)。「GCC4.6リリースシリーズ–変更、新機能、および修正」Gcc.gnu.org2013年12月2日にオリジナルからアーカイブされました2013年11月27日取得
  42. ^ 「ブロックプログラミングトピック–Mac開発者ライブラリ」Apple Inc. 2011年3月8日。2012年6月5日のオリジナルからアーカイブ2012年11月28日取得
  43. ^ a b "Objective-C自動参照カウント(ARC)— Clang11ドキュメント"Clangのドキュメント2020年2月20日取得今のところ、このドキュメントは、その唯一の実装(およびそのホストプロジェクト)であるclangのリリースによってバージョン管理するのが賢明です。「LLVMXY」は、LLVMプロジェクトからのclangのオープンソースリリースを指します。「AppleXY」とは、Appleが提供するAppleLLVMコンパイラのリリースを指します。
  44. ^ 「ARCへの移行」Apple Inc. 2011年9月7日のオリジナルからアーカイブ2012年10月8日取得
  45. ^ 「LLVM3.0リリースノート」releases.llvm.org
  46. ^ a b 「Objective-Cを使用したプログラミング:値とコレクション」Apple Inc. 2011年9月7日のオリジナルからアーカイブ2012年10月8日取得
  47. ^ 「Clang3.1リリースノート」releases.llvm.org
  48. ^ 「Objective-Cリテラル— Clang3.5ドキュメント」Clang.llvm.org。2014年6月6日にオリジナルからアーカイブされました2014年4月16日取得
  49. ^ Rhapsody開発者ガイド、AP Professional、1997年、76〜84ページ
  50. ^ 「ポータブルオブジェクトコンパイラ」Users.pandora.be。1970年1月1日。2008年8月2日のオリジナルからアーカイブ2010年5月30日取得
  51. ^ 「BreadboxComputerCompanyLLCホームページ」2011年7月27日にオリジナルからアーカイブされました2010年12月8日取得
  52. ^ "gcc / libobjc"GitHubgcc-mirror。2020年1月6日2020年1月6日取得ランタイムはgcc2.4で完全に書き直されました。以前のランタイムにはいくつかの重大なバグがあり、かなり不完全でした。
  53. ^ 「GNUObjective-CランタイムAPI」GCCを使用します。2020年1月6日取得
  54. ^ 「GitHub上のWinObjC」GitHub2017年12月2日にオリジナルからアーカイブされました2018年2月13日取得
  55. ^ 「GNUStepインストーラー」2018年2月17日にオリジナルからアーカイブされました2018年2月14日取得
  56. ^ Apple、Inc。(2006年8月22日)。「MacOSX Leopard –Xcode3.0」apple.com。2007年10月24日にオリジナルからアーカイブされました2006年8月22日取得
  57. ^ 「ARCリリースノートへの移行」iOS開発者ライブラリDeveloper.apple.com。2011年9月7日にオリジナルからアーカイブされました2014年4月16日取得

さらに読む

  • コックス、ブラッドJ.(1991)。オブジェクト指向プログラミング:進化的アプローチアディソンウェスリー。ISBN 0-201-54834-8

外部リンク