1. ホーム
  2. iphone

[解決済み] Objective-Cのプロトコルでプロパティを含むものはどう扱えばいいのか?

2022-06-17 06:49:59

質問

Objective-Cのプロトコルは、次のような使われ方をしているのを見たことがあります。

@protocol MyProtocol <NSObject>

@required

@property (readonly) NSString *title;

@optional

- (void) someMethod;

@end

サブクラスが拡張する具体的なスーパークラスを書く代わりに、この形式が使われているのを見たことがあります。問題は、このプロトコルに準拠する場合、プロパティを自分で合成する必要があるのかどうかです。スーパークラスを拡張しているのであれば、答えは明らかに「いいえ」です。しかし、プロトコルが準拠を要求するプロパティをどのように扱うのでしょうか?

私の理解では、これらのプロパティを必要とするプロトコルに準拠するオブジェクトのヘッダーファイルで、やはりインスタンス変数を宣言する必要があります。その場合、それらは単なる指針に過ぎないと考えていいのでしょうか?ほとんど同じことが、必須メソッドの場合にも当てはまらない。プロトコルに記載されている必須メソッドを除外すると、コンパイラに手首を叩かれます。しかし、プロパティの裏側はどうなっているのでしょうか?

以下はコンパイルエラーを発生させる例です(注:手元の問題に反映されないコードを切り捨てました)。

MyProtocol.h

@protocol MyProtocol <NSObject>

@required
@property (nonatomic, retain) id anObject;

@optional

TestProtocolsViewController.h

- (void)iDoCoolStuff;

@end

#import <MyProtocol.h>

@interface TestProtocolsViewController : UIViewController <MyProtocol> {

}

@end

TestProtocolsViewController.m

#import "TestProtocolsViewController.h"

@implementation TestProtocolsViewController
@synthesize anObject; // anObject doesn't exist, even though we conform to MyProtocol.

- (void)dealloc {
    [anObject release]; //anObject doesn't exist, even though we conform to MyProtocol.
    [super dealloc];
}

@end     

どのように解決するのですか?

プロトコルは、プロトコルを介してあなたのクラスを知っている人全てに、プロパティ anObject が存在することを伝えているだけです。 プロトコルは本物ではなく、それ自身は変数やメソッドを持ちません。プロトコルは、あなたのクラスについて真である属性の特定のセットを記述するだけなので、それへの参照を持つオブジェクトは特定の方法でそれらを使用することができます。

つまり、プロトコルに準拠したクラスでは、anObjectが動作するようにあらゆることをしなければならないのです。

@property@synthesize は、要するにコードを生成してくれる二つの機構です。 @property は、そのプロパティ名に対するゲッター(および/またはセッター)メソッドが存在することを示すだけです。 最近では @property だけで、システムによって作成されたメソッドとストレージ変数を持つことができるようになりました (以前は、このプロパティに @sythesize ). しかし、変数にアクセスし、保存するための何かを持っていなければなりません。