简体   繁体   中英

Why should I conform Custom Protocol to NSObject?

Any object which assign to Custom protocol reference, is always be Confirm by NSObject Protocol directly or By superclasses. So Why should I do this?

It sounds like you might be trying to ask about using the NSObject protocol, since every class has NSObject as an ancestor.

The answer, then, is that it's not true that every object is derived from NSObject . Most are, but NSProxy is an example of one that's not. The methods in the NSObject protocol are what any instance of the NSObject class is expected to implement, so by implementing the NSObject protocol , NSProxy is able to provide the same behaviors that any class derived from NSObject (class) has.

For example, you can use methods like -isEqual and -hash with instances of NSProxy .

If you're creating a subclass of the NSObject class, there's no need to declare that your class implements the NSObject protocol because the NSObject class already does that for you.

Also, just as you can declare that a class adopts a protocol with:

@interface MyClass <SomeProtocol>

you can also declare that a protocol adopts another protocol:

@interface MyProtocol <SomeProtocol>

Since, as explained above, not every class is a subclass of NSObject (the class), having MyProtocol adopt NSObject (the protocol) guarantees that you can call NSObject methods. If you want to specify that a method takes any kind of object that adopts YourProtocol , you can do that by specifying the type as id<YourProtocol> . However, if YourProtocol isn't declared to adopt the NSObject protocol, you can't be certain that it's safe to call NSObject methods like -isEqual , and you can't even check that it's safe using -respondsToSelector: or -isKindOfClass: because those methods themselves are part of the NSObject protocol.

I really don't know, whether I got you right.

If you meant that a custom protocol always confirms to the NSObject protocol, there is a pretty simply reason for it. It is a little bit weird:

If you type a reference to id the compiler accepts every message to that he has seen while compiling the translation unit ("class", "module", the file you compile).

If you type an object reference to id<protocol> , the compiler only accepts messages that are declared inside the protocol. But this is never enough!

@protocol MyProtocol
@optional
- (void)doItOrNot;
@end

The only message you can send is -doItOrNot . So the compilation of such code will fail:

id<MyProtocol> ref = …;
if ([ref respondsToSelector:@selector(doItOrNot)]) // <- Error -respondsToSelector is not declared in the protocol.
…

By adding the NSObject protocol to your protocol you import some fundamental declarations. (Including MM for MRC.)

Cocoa defines an NSObject protocol that mirrors the NSObject class and instance methods. By declaring that your custom protocol implements the NSObject protocol, you give the compiler a hint that all of the NSObject methods will be implemented by an instance that implements your custom protocol.

If you don't include the NSObject protocol, you'll get warnings when you try to call any of the NSObject methods for instance respondsToSelector: on the object.

You don't have to. But the problem is that a lot of the core functionality of NSObject — indeed, all the core functionality necessary for NSObject to function as a base class — is declared in the NSObject protocol. (This strange architecture is so that both NSObject and NSProxy can be base classes: they both adopt the NSObject protocol.)

Now, if you declare an object's type as id<MyDelegate> , the only messages you can send that object are MyDelegate messages. That's fine, usually; but what if you want to send it, say, the respondsToSelector: message? That method is declared in the NSObject protocol, not in the MyDelegate protocol. So the compiler will stop you.

There are two solutions. Either declare the object's type as NSObject<MyDelegate> , or make MyDelegate adopt the NSObject protocol. Either way, the compiler is now satisfied, and you can send this object the respondsToSelector: message.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM