Подтвердить что ты не робот

Почему протоколы Objective-c используют другие протоколы?

Я видел протоколы Objective-c, определенные следующим образом:

@protocol MyProtocol <SomeOtherProtocol>
// ...
@end

Почему протоколы принимают другие протоколы? Мне особенно любопытно, почему протокол принимает протокол NSObject.

4b9b3361

Ответ 1

Это просто та же концепция, что и наследование для классов. Если протокол принимает другой протокол, он "наследует" объявленные методы этого принятого протокола.

Протокол NSObject особенно объявляет такие методы, как respondsToSelector:. Поэтому это особенно полезно, если вы объявляете @protocol, у которого есть методы @optional, потому что когда вы вызовете методы на объектах, соответствующих этому протоколу, вам нужно будет проверить, отвечает ли объект методу перед его вызовом, если этот метод необязательно.


@protocol SomeProtocol <NSObject>
-(void)requiredMethod;
@optional
-(void)optionalMethod;
@end

@interface SomeObject : NSObject
-(void)testMyDelegate;
@property(nonatomic, assign) id<SomeProtocol> myDelegate;
@end

@implementation SomeObject
@synthesize myDelegate

-(void)testMyDelegate {
    // Here you can call requiredMethod without any checking because it is a required (non-optional) method
    [self.myDelegate requiredMethod];

    // But as "optionalMethod" is @optional, you have to check if myDelegate implements this method before calling it!
    if ([myDelegate respondsToSelector:@selector(optionalMethod)]) {
        // And only call it if it is implemented by the receiver
        [myDelegate optionalMethod];
    }
}
@end

Вы можете только respondsToSelector вызывать на myDelegate, если myDelegate объявлен как тип, который реализует respondsToSelector (в противном случае у вас появятся некоторые предупреждения). Вот почему протокол <SomeProtocol> должен принять сам протокол <NSObject>, который сам объявляет этот метод.

Вы можете думать о id<SomeProtocol> как "любом объекте, независимо от его типа (id)), он просто должен реализовать методы, объявленные в SomeProtocol, включая методы, объявленные в родительском протоколе NSObject. он может быть объектом любого типа, но , потому что SomeProtocol принимает сам протокол NSObject, гарантируется, что вам разрешено вызывать respondsToSelector на этом объекте, позволяя вам проверить, реализует ли объект данный перед вызовом его, если он является необязательным.


Обратите внимание, что вы также не можете сделать SomeProtocol принять протокол NSObject и вместо этого объявить свою переменную как id<SomeProtocol,NSObject> myDelegate, чтобы вы все равно могли вызвать respondsToSelector:. Но если вы это сделаете, вам нужно будет объявить все ваши переменные таким образом везде, где вы используете этот протокол... Так что гораздо логичнее сделать SomeProtocol непосредственно принять протокол NSObject;)

Ответ 2

Наследование...................