3

簡単なテストで何かを試してみたところ、次のコードで質問があります。

@protocol stuffieProtocol <NSObject>
@required 
-(void)favouiteBiscuit;
@end

.

// DOG & TED ARE IDENTICAL, THEY JUST LIKE DIFFERENT BISCUITS
@interface Dog : NSObject <stuffieProtocol>
@property (strong, nonatomic) NSString *name;
@end

@implementation Dog

- (id)init {
    return [self initWithName:@"Unknown"];
}

- (id)initWithName:(NSString *)name {
    self = [super init];
    if(self) {
        _name = name;
    }
    return self;
}

- (void)whoAreYou {
    NSLog(@"MY NAME IS: %@ I AM A: %@", [self name], [self class]);
}
- (void)favouiteBiscuit {
    NSLog(@"FAVOURITE BISCUIT IS: Costa Jam Biscuit");
}
@end

.

Dog *stuffie_001 = [[Dog alloc] initWithName:@"Dog Armstrong"];
Ted *stuffie_002 = [[Ted alloc] initWithName:@"Teddy Sullivan"];

NSArray *stuffieArray = @[stuffie_001, stuffie_002];
for(id<stuffieProtocol> eachObject in stuffieArray) {
    [eachObject whoAreYou]; // << ERROR
    [eachObject favouiteBiscuit];
}

私の質問は、エラーが発生することです"ARC Semantic Issue: No known instance method for selector 'whoAreYou'"

プレフィックスを付ける[eachObject whoAreYou];[(Dog *)eachObject whoAreYou];、これはループのすべての反復で機能しますが、配列内のすべてのオブジェクトがタイプではないため、それは間違っているように感じますDog

これを正しくするには、何を前に付ける必要がありますか?

4

2 に答える 2

2

追加

-(void) whoAreYou;

あなたのプロトコルに。次に、コンパイラeachObjectは、ループ内でそのメソッドに応答することを認識します。

于 2012-08-02T11:16:18.553 に答える
2

各オブジェクトを ID として宣言します。

これは、コンパイラがオブジェクトの種類を認識していないことを意味します

それはプロトコル stuffieProtocol を実装していることを知っているだけなので、確実に次のメソッドに応答できます: favouiteBiscuit

ただし、whoAreYou メソッドに応答できるかどうかはわかりません。

これを回避するために多くのことができます

最も簡単なのは次のとおりです。

eachObject がセレクター whoAreYou を実行できるかどうかを尋ねることができます。この場合、そのセレクターを実行します。

if ([eachObject respondsToSelector:@selector(whoAreYou) ]) {
    [eachObject performSelector:@selector(whoAreYou) ];
}

このようにして、コンパイラは、各オブジェクトがメソッドwhoAreYouを実装するかどうかを制御することを回避します

それは実行時に行われるので、各オブジェクトにメソッド whoAreYou があれば、それが呼び出されます。

もう 1 つの方法は、ted と dog の両方に共通のスーパークラスを作成することです。

(例 SuperClassOfTedAndDog <stuffieProtocol> )

そのスーパークラスでメソッド whoAreYou を宣言し、for ループで ID の代わりにそのスーパークラスを使用します。

for(SuperClassOfTedAndDog* eachObject in stuffieArray) {
    [eachObject whoAreYou]; 
    [eachObject favouiteBiscuit];
}
于 2012-08-02T11:10:49.117 に答える