Pregunta

I am little confused about some concepts around Objective-C protocols and categories.

Can protocols and categories be inherited by subclasses in Objective-C?

¿Fue útil?

Solución

Categories are collections of methods that are added to a class at run time. Because Objective-C uses dynamic binding, this means that the methods defined in a category are available to the class and all of its subclasses. Specifically selectors are bound to methods at the point where they are invoked, not during compilation or when the program first loads. Categories are added to classes when they (the categories) are loaded.

Protocols define collections of method signatures that the classes conforming to them promise to implement. Once a class has declared that it conforms to a protocol its as if the methods are declared in that class's interface and the rules of inheritance are exactly the same: subclasses inherit the declaration and implementation of the protocol methods but may also choose to override the superclass implementation.

Protocols themselves can be extended to produce new protocols. consisting of a superset of the methods in the original protocol. In fact, just as most classes inherit from the NSObject class, most protocols extend the NSObject protocol (protocol names and class names are in different name spaces). This is so that objects declared as id<WhateverProtocol> can be sent basic messages like -retain, -release and so on without generating compiler warnings.

Otros consejos

Categories are like an extension to a class. You can add your own methods to other classes (such as NSString or anything else). Which means that any subclass gets the methods as well.

Whereas a protocol are a list of methods that requires the class that confirms to it to implement all of it (unless it uses the @optional tag). So there is no point of it's subclass to inherit it.

Edit:

For the protocol implementation, I realized I wasn't clear enough. Protocol Methods that were implemented in it's superclass can be inherited, however, what I meant was usually you don't need to override your superclass's protocol method.

Your question is unclear. You may be asking whether subclasses inherit the protocols and categories of their superclass. @theAmateurProgrammer has answered this.

You may also be asking whether categories and protocols can themselves inherit from other categories and protocols. For categories, the answer is no. For protocols, the answer is yes, and in fact protocols should almost always inherit just like classes like this:

@protocol SomeProtocol <NSObject>
...
@end

This says that anything that conforms to <SomeProtocol> also conforms to <NSObject> (which is a protocol as well as a class). This allows you to call methods like respondsToSelector:, which is very important for most protocol implementations.

Protocols are like interfaces in Java. So, a class provides a protocol for accessing it.

You can "subclass" protocols just like in Java you can "subclass" interfaces.

Categories on the other hand are a way to add more methods to a class. The restriction is you can't add any instance variables with a category. You can only access the existing instance variables.

It's very useful though because it avoids creating a large fragile subclass hierarchy.

So, bottom line is, if you want a view different classes to conform to a standard interface, then use a protocol. If you want to add a few methods to an existing class without the hassle of subclassing, go for a category.

However, one thing to bear in mind is that when you add methods to a category - something I've been reminded of by workmates - is that you're making those methods available everywhere. I've read in a few places that a common newbie mistake is to go crazy with categories, using them all the time instead of creating new classes that would do the job.

So, if the new category method that you're considering is really specific or rather - tightly coupled - to a business function, then probably it shouldn't be a category. They really should only be used for generic additions to the base class.

NSObject conforms to NSObject protocol

@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}

Say we have a subclass of NSObject

@interface FTGAnimal : NSObject

@end

@implementation FTGAnimal

@end

We can see that FTGAnimal actually conforms to NSObject protocol

if ([FTGAnimal conformsToProtocol:@protocol(NSObject)]) {
        NSLog(@"FTGAnimal conforms to NSObject protocol");
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top