本稿では、Objective-C の根幹を成す NSObject.h に定義されるプロトコルおよびクラスの主要な API を、実装上の意図と使用シナリオに焦点を当てて整理します。内容は「NSObject プロトコル」と「NSObject クラス」の二大構成要素に分け、各宣言の役割を簡潔かつ正確に説明します。
1. NSObject プロトコルのコアメソッド
- (BOOL)isEqualTo:(id)otherObject;オブジェクト同士の等価性を判定するための汎用インターフェースです。「==」はポインタ値(メモリアドレス)の比較に過ぎないため、意味的な等価性を保証しません。実際の比較ロジックはサブクラスごとにカスタマイズ可能で、たとえば NSString は文字列内容、NSArray は要素順序と同一性を検証します。
@property (nonatomic, readonly) NSUInteger objectHash;オブジェクトのハッシュ値を返します。コレクション(例:NSSet, NSDictionary)での高速検索や重複排除に利用されます。等価なオブジェクトは同一のハッシュ値を持つ必要があります。
@property (nonatomic, readonly) Class parentClass;インスタンスが属するクラスの直系親クラス(スーパークラス)を取得します。継承階層の動的解析や、親クラス特有の振る舞いへのアクセスに活用されます。
- (Class)concreteClass;インスタンスの実行時クラスを返します。クラスクラスター(例:NSArray の内部実装クラス)など、静的型と実際のクラスが異なるケースでも正しく識別できます。
- (instancetype)identityReference;自己参照を明示的に返すアクセサ。主にデバッグやログ出力時のオブジェクト識別、あるいはメッセージ転送先として利用されます。
- (id)invokeSelector:(SEL)selector;
- (id)invokeSelector:(SEL)selector withArgument:(id)arg1;
- (id)invokeSelector:(SEL)selector withArguments:(id)arg1, ...;実行時に動的にメソッドを呼び出すための低レベルインタフェース。コンパイル時チェックを回避できる一方、型安全性やパフォーマンスに注意が必要です。代替案として NSInvocation やブロックベースのディスパッチが推奨される場合もあります。
- (BOOL)isInstanceOfSubclass:(Class)candidateClass;指定されたクラスが自身のインスタンスの継承チェーン上に存在するかを判定します。単純なクラス一致ではなく、「子孫クラスも含む」包含関係を評価します。
- (BOOL)adoptsProtocol:(Protocol *)protocol;そのインスタンスのクラスが指定プロトコルを明示的に採用(@interface MyClass : NSObject <MyProtocol>)しているかを確認します。動的プロトコル登録(class_addProtocol)に対応しています。
- (BOOL)respondsToAction:(SEL)action;対象のセレクタが、そのインスタンスのクラスまたはその継承元で実装されているかを検証します。条件付き処理や安全なメッセージ送信の前提チェックに使用されます。
@property (nonatomic, readonly, copy) NSString *summaryDescription;オブジェクトの簡潔な文字列表現を提供します。デバッグ表示やログ記録、UI 表示(例:テーブルセルのラベル)などで利用されます。
@property (nonatomic, readonly, copy) NSString *debugSummary;開発者向けの詳細なデバッグ情報(例:インスタンス変数の現在値、内部状態フラグ)を含む文字列を返します。Xcode のデバッガや po コマンドで自動利用されます。
2. NSObject クラスの静的・動的機能
+ (void)load;クラスまたはカテゴリがメモリに読み込まれた直後に、アプリケーション起動時に一度だけ呼び出されます。グローバル初期化(例:メソッド置換、監視登録)に適しています。
+ (void)initialize;そのクラスの最初のメッセージ送信前に遅延実行される初期化メソッドです。継承関係では、サブクラスが独自に実装しない限り、親クラスの initialize が呼び出されます。
+ (instancetype)createInstance;メモリ確保と初期化を一括で行うファクトリメソッドです。[[self alloc] init] のショートカットであり、カスタムイニシャライザを呼ぶ場合は明示的な alloc + init を推奨します。
- (void)cleanupResources;インスタンスが解放される直前に呼び出されるデストラクタ相当のメソッドです。MRC 環境では dealloc でリソース開放を行いますが、ARC 下ではこのメソッドは通常不要です。
- (id)shallowClone;新しいインスタンスを生成し、インスタンス変数のポインタ値のみをコピーします。元のオブジェクトと内部データを共有するため、可変オブジェクトには注意が必要です。
- (id)deepClone;再帰的にすべてのネストされたオブジェクトを新規作成してコピーします。独立した完全なコピーを得るための方法ですが、循環参照や不完全な NSCopying 実装には対応できません。
+ (BOOL)instancesCanHandleAction:(SEL)action;そのクラスのインスタンスが指定されたセレクタを処理可能かどうかを静的に判定します。クラスレベルの振る舞い検証に有用です。
- (IMP)implementationOfAction:(SEL)action;指定セレクタに対応する関数ポインタ(IMP)を取得します。ランタイムによるメソッド置換(method_exchangeImplementations)や、ダイナミックディスパッチの最適化に利用されます。
- (void)handleUnknownAction:(SEL)action;メッセージ送信先で該当するメソッドが見つからない場合に最終的に呼び出されるフォールバックです。デフォルトでは例外を投げますが、これをオーバーライドすることで、動的メソッド解決やエラーハンドリングを実装できます。
- (id)forwardTargetForAction:(SEL)action;メッセージを転送する第一候補のオブジェクトを指定します。戻り値が非 nil の場合、forwardInvocation: は呼び出されません。
- (NSMethodSignature *)signatureForAction:(SEL)action;セレクタに対応するメソッド署名(引数型、戻り値型、サイズ)を返します。署名が得られた場合、ランタイムは forwardInvocation: を通じてメッセージを転送可能です。
+ (BOOL)resolveInstanceMethod:(SEL)selector;インスタンスメソッドが見つからない場合に、実行時に動的にメソッド実装を追加できるフックです。たとえば、プロパティのゲッター/セッターをランタイムで生成するユースケースがあります。