为什么 Objective-c 协议采用其他协议?

发布于 2024-12-06 04:49:08 字数 197 浏览 1 评论 0原文

我见过 Objective-c 协议的定义方式如下:

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

为什么协议采用其他协议? 我特别好奇为什么协议会采用 NSObject 协议。

I've seen Objective-c protocols defined in the following way:

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

Why do protocols adopt other protocols? I'm especially curious why a protocol would adopt the NSObject protocol.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨小沫ゞ 2024-12-13 04:49:08

它与类的继承是相同的概念。
如果一个协议采用了另一个协议,它就会“继承”该采用的协议所声明的方法。

NSObject 协议特别声明了诸如 respondsToSelector: 之类的方法。因此,如果您声明具有 @optional 方法的 @protocol ,这尤其有用,因为当您调用符合此协议的对象上的方法时,您将需要检查是否如果此方法是可选的,则对象会在调用该方法之前响应该方法。


@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

如果 myDelegate 声明为实现 respondsToSelector 的类型,则您只能在 myDelegate 上调用 respondsToSelector(否则您会收到一些警告)。这就是为什么 协议需要采用 协议,该协议本身声明了此方法。

您可能会将 id 视为“任何对象,无论其类型如何 (id),它只需实现 SomeProtocol 中声明的方法即可>,包括父协议 NSObject 中声明的方法,因此它可以是任何类型的对象,但因为 SomeProtocol 采用 NSObject。 > 协议本身,保证您可以在此对象上调用 respondsToSelector,从而允许您在调用给定方法(如果是可选的)之前检查该对象是否实现了给定方法


请注意,您也可以不这样做 。 SomeProtocol 采用 NSObject 协议,并将变量声明为 idmyDelegate ,以便您仍然可以调用respondsToSelector:,但是如果你这样做,你将需要在使用此协议的任何地方都以这种方式声明所有变量......所以直接创建 SomeProtocol 更符合逻辑。采用 NSObject 协议;)

It is simply the same concept as inheritance for classes.
If a protocol adopt another protocol, it "inherits" the declared methods of this adopted protocol.

The NSObject protocol especially declares methods such as respondsToSelector:. So this is especially useful if you declare a @protocol that have @optional methods, because when you will then call methods on objects conforming this protocol, you will need to check if the object responds to the method before calling it if this method is 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

You will only be able to call respondsToSelector on myDelegate if myDelegate is declared as a type that implements respondsToSelector (otherwise you will have some warnings). That's why the <SomeProtocol> protocol needs to adopt itself the <NSObject> protocol, which itself declares this method.

You may think of id<SomeProtocol> as "any object, whatever its type (id), it just has to implement the methods declared in SomeProtocol, including the methods declared in the parent protocol NSObject. So it can be an object of any type but because SomeProtocol adopts the NSObject protocol itself, it is guaranteed that you are allowed to call respondsToSelector on this object, allowing you to check if the object implements a given method before calling it if it is optional.


Note that you may also not make SomeProtocol adopt the NSObject protocol and instead declare your variable as id<SomeProtocol,NSObject> myDelegate so that you can still call respondsToSelector:. But if you do that you will need to declare all your variables this way everywhere you use this protocol... So this is much more logical to make SomeProtocol directly adopt the NSObject protocol ;)

羁绊已千年 2024-12-13 04:49:08

遗产...................

Inheritance...................

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文