LoginSignup
4
4

More than 5 years have passed since last update.

カテゴリーでインスタンス変数

Last updated at Posted at 2014-05-28

Objective-C で既存のクラスを拡張する方法のひとつにカテゴリーを利用する方法があります。

@interface MyClass (CategoryName)

// 追加したいメソッド

@end

カテゴリーですでにあるメソッドと同じ名前のメソッドを追加するとどっちのメソッドが利用されるか分からなくなってしまうという強烈な副作用があるため、利用には注意が必要です。

カテゴリーではインスタンス変数 (メンバー変数) を追加することはできない……と思っていたんですが、私の勘違い?もしかして以前とは動作が変わりました?

@interface MyClass (CategoryName)
{
  id _newMember; // <= これは無理
}

- (void)newMethod;

@end

@interface MyClass ()
{
  id _newMember; // <= これは OK
}

@end

というコードはできないと思っていたんですが、どうも勘違いだってみたいで普通にできる様子。

やっぱり勘違いでした。カテゴリー名を省略する anonymous categories は「クラス拡張 Class Extensions」とも言って、こっちだとインスタンス変数の宣言ができるようです。

@interface MyClass (CategoryName)
{
  id _newMember; // <= これは無理
}

- (void)newMethod1;
- (void)newMethod2;

@end

@interface MyClass ()
{
  id _newMember; // <= これは OK
}
@end

@implementation MyClass (CategoryName)

- (void)newMethod1
{
  _newMember = ...; // なんか代入
}

- (void)newMethod2
{
  NSLog(@"%@",_newMember); // newMethod1 に先にアクセスしていれば、その内容がちゃんと見れる
}

@end

@tomohisaota さんご指摘の通り、この拡張はコンパイラーによって行われるので、ソースコードにアクセスできるような状態でないといけない模様。

UIKit など既存のフレームワークで宣言されたクラスの拡張にはできないようです。試しにやってみたら、リンカでエラーになりました。

Xcode 5.1.1 / iOS SDK 7.1 & OS X SDK 10.9 で確認。

@tomohisaota さん、ありがとうございます。

4
4
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4