Apple Developer Connection
Advanced Search
Member Login Log In | Not a Member? Contact ADC

< Previous PageNext Page >

ルートクラス

Objective-Cの言語とランタイムだけでは、最も単純なオブジェクト指向プログラムさえ構築するには十分ではありません。少なくとも、簡単ではありません。すべてのオブジェクトに共通する基本的な動作とインターフェイスの定義という、重要な要素が欠けています。それらの定義を提供するのがルートクラスです。

ルートクラスは、クラス階層(この場合はCocoaのクラス階層)のルートに位置することからその名が与えられています。ルートクラスはほかのどのクラスも継承せず、階層内のほかのすべてのクラスは最終的にルートクラスを継承します。Objective-Cの言語とともに、ルートクラスはCocoaがObjective-Cのランタイムに直接アクセスしてやり取りする際の中心的な場所になります。Cocoaオブジェクトのオブジェクトとしての動作機能は、主にルートクラスに由来します。

CocoaではNSObjectNSProxyの2種類のルートクラスが用意されています。Cocoaでは、抽象スーパークラスである後者のクラスを、ほかのオブジェクトの代役として機能するオブジェクトとして定義しています。そのため、NSProxyは分散オブジェクトアーキテクチャにおいて必要不可欠です。このような特別な役割のため、NSProxyはCocoaプログラムではあまり登場しません。Cocoaの開発者がルートクラスや基本クラスを引き合いに出すときは、ほとんど常にNSObjectのことを指しています。

このセクションでは、NSObjectについて説明し、NSObjectとランタイムとのやり取り、およびすべてのCocoaオブジェクトに対してNSObjectで定義されている基本的な動作とインターフェイスについて、解説します。特に、割り当て、初期化、メモリ管理、イントロスペクション、およびランタイムサポートを行うために宣言されている各メソッドについて説明します。これらの概念はCocoaを理解するための基礎になります。

In this section:

NSObject
ルートクラス、およびプロトコル
ルートクラスのメソッドの概要
インターフェイスに関する規則
インスタンスメソッドとクラスメソッド


NSObject

NSObjectはほとんどのObjective-Cクラス階層のルートクラスであり、スーパークラスを持ちません。ほかのクラスは、 Objective-C言語のランタイムシステムへの基本的なインターフェイスをNSObjectから継承し、そのインスタンスは、オブジェクトとして動作する機能を得ます。

NSObjectは厳密には抽象クラスではありませんが、事実上抽象クラスであると言えます。NSObjectのインスタンスは単独では、単純なオブジェクトとして存在する以外に、役に立つことはできません。プログラムに対して固有の属性やロジックを追加するには、NSObjectクラスを継承するクラス、またはNSObjectから派生したほかのクラスを継承するクラスを、1つ以上作成する必要があります。

NSObjectでは NSObjectプロトコルを採用しています(“「ルートクラス、およびプロトコル」”を参照)。NSObjectプロトコルでは、複数のルートオブジェクトの使用が可能です。たとえば、もう一方のルートクラスであるNSProxyは、NSObjectを継承しませんが、NSObjectプロトコルを採用しているため、ほかのObjective-Cオブジェクトと共通のインターフェイスを共有します。

NSObjectは java.lang.Objectとともに、FoundationとApplication Kitを含め、JavaにおけるすべてのCocoa要素のルートクラスになります。

ルートクラス、およびプロトコル

NSObjectはクラスの名前だけではなくプロトコルの名前も表します。どちらも、Cocoaにおけるオブジェクトの定義に必要不可欠です。NSObjectプロトコルでは、Cocoa内のすべてのルートクラスに必要とされる基本的なプログラムインターフェイスを規定しています。そのため、NSObjectプロトコルはまったく同じ名前のクラスで採用されているだけでなく、もう一方のCocoaルートクラスであるNSProxyでも採用されています。NSObjectクラスではさらに、プロキシオブジェクトではないすべてのCocoaオブジェクトに対する基本的なプログラムインターフェイスも規定しています。

NSObjectなどのプロトコルは、複数のルートクラスを可能にするために、それらのプロトコルメソッドをクラスインターフェイスに含めるのではなく、Cocoaオブジェクトの定義全体で使用されます。ルートクラスはそれぞれ、採用しているプロトコルによって定義されている共通のインターフェイスを共有します。

別の言い方をすれば、NSObjectだけが唯一の“ルート”プロトコルではありません。NSObjectクラスでは、NSCopyingNSMutableCopyingNSCodingの各プロトコルが正式には採用されていませんが、これらのプロトコルに関連するメソッドが宣言され実装されています(さらに、NSObjectクラスの定義が含まれているNSObject.hヘッダファイルには、前述の4つのプロトコルすべての定義が含まれています)。オブジェクトのコピー、エンコード、およびデコードは、オブジェクトの動作の基本的な一面です。ほとんどすべてというわけではありませんが、サブクラスの多くは、これらのプロトコルの採用またはプロトコルへの準拠が想定されています。

注: ほかのCocoaクラスは、カテゴリを通じてメソッドをNSObjectに追加することができ、また実際に追加しています。これらのカテゴリはしばしば委任で使用される簡易プロトコルであり、カテゴリのどのメソッドを実装するかをデリゲートが選べるようにしています。ただし、NSObjectのこれらのカテゴリは、基本オブジェクトインターフェイスの一部とは見なされません。

ルートクラスのメソッドの概要

NSObjectルートクラスは、採用されているNSObjectプロトコルやほかの“ルート”プロトコルとともに、プロキシ以外のすべてのCocoaオブジェクトに対して、次のインターフェイス特性と動作特性を規定します。

このほか、NSObjectのメソッドにはバージョン管理やなりすましのためのクラスメソッドなどがあります(なりすましを使用すると、クラスがランタイムに対して別のクラスとして見えるようにすることができます)。また、メソッドセレクタや、メソッド実装への関数ポインタなど、実行時のデータ構造にアクセスできるメソッドもあります。

インターフェイスに関する規則

NSObjectメソッドには、呼び出されることのみを目的とするものや、オーバーライドを意図したものがあります。たとえば、ほとんどのサブクラスではallocWithZone:をオーバーライドせずに、initを実装することが求められます。あるいは少なくとも、最終的にルートクラスのinitメソッドを呼び出すイニシャライザを実装することが求められます(“「オブジェクトの作成」”を参照)。サブクラスによるオーバーライドを前提としたメソッドのうち、NSObjectに実装されているものは、何も実行しないか、selfなどの妥当なデフォルト値を返すかのどちらかです。このようなデフォルト実装のおかげで、クラスにおいてメソッドをオーバーライドしていないオブジェクトを含め、任意のCocoaオブジェクトに対して、initなどの基本的なメッセージを、実行時例外発生の危険を冒すことなく送信することが可能になります。メッセージを送信する前に(respondsToSelector:を使用して)チェックする必要はありません。さらに重要なこととして、NSObjectの“プレースホルダ”メソッドによって、Cocoaオブジェクトの共通の構造が定義され、オブジェクトのやり取りの信頼性が向上する規則が確立されます(すべてのクラスがその規則に従う場合)。

インスタンスメソッドとクラスメソッド

ランタイムシステムでは、ルートクラスで定義されているメソッドが特別な方法で扱われます。ルートクラスで定義されているインスタンスメソッドは、インスタンスとクラスオブジェクトの両方で実行できます。したがって、すべてのクラスオブジェクトが、ルートクラスに定義されているインスタンスメソッドにアクセスできます。同じ名前のクラスメソッドを持っていない限り、どのクラスオブジェクトも、ルートの任意のインスタンスメソッドを実行できます。

たとえば、クラスオブジェクトにメッセージを送信して、NSObjectrespondsToSelector:とインスタンスメソッドperformSelector:withObject:を実行できます。

SEL method = @selector(riskAll:);
 
if ([MyClass respondsToSelector:method])
    [MyClass performSelector:method withObject:self];

クラスオブジェクトで使用できるインスタンスメソッドは、そのルートクラスで定義されているものだけです。上記の例では、仮にMyClassにおいてrespondsToSelector:performSelector:withObject:のどちらかを再実装したとすれば、それらの新しいバージョンはインスタンスにおいてのみ使用できます。MyClassのクラスオブジェクトでは、NSObjectクラスに定義されているバージョンだけを実行できます(もちろん、MyClassにおいてrespondsToSelector:またはperformSelector:withObject:をインスタンスメソッドとしてではなくクラスメソッドとして実装した場合には、それらの新しいバージョンがクラスで実行されることになります)。



< Previous PageNext Page >


Last updated: 2006-05-23




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice