In the section of code below, what exactly does the <UIScrollViewDelegate> part mean and do? what would it most likely be used for and what would most likely happen if it was removed? (any theoretical example is good)
#interface PhoneContentController : ContentController <UIScrollViewDelegate>
It means that PhoneContentController adopts the ObjC protocol named UIScrollViewDelegate.
A protocol is an interface of methods without definition. When the class adopts it, it advertises that it implements the methods declared by the protocol.
This is a common feature in OOD for an abstract type, particularly in languages which use single inheritance only. If you know Java, it's much like implements UIScrollViewDelegate.
Related
The "Objective-C for Java Programmers, Part 1" intro by David Chisnall states that
Because you can have multiple base classes, Objective-C introduces the
id type to represent a pointer to some kind of object. You can
implicitly cast between any object type and id.
To the best of my understanding, Objective-C is single-inheritance (just like Java, but unlike C++).
So what does "multiple base classes" mean (in this context)?
It means that you can define your own root or "base" class.
#interface MyRootClass
#end
Note that it does not inherit from NSObject.
In practice, this is never done because said class can't really be used inter-operably with the rest of the system APIs because they all expect NSObject inherited behavior.
That isn't really the motivation behind the id type, though. The id type means, quite literally, this object reference can be an instance of any class.
That there may be multiple base classes is entirely orthogonal.
No, implementing the NSObject #protocol isn't really good enough.
I'm struggling with naming protocols in Objective-C. For example:
I have a protocol called Command.
I have an abstract class that implements Command that is a base class for my concrete Commands.
I believe it is possible to call both the protocol and the base class 'Command' but this is confusing and will cause import clashes if I need to reference the protocol in an implementation. I also understand that in Objective C, using a prefix to denote a protocol is bad form. Some examples use 'ing' added to the end, but in this instance that makes no sense. Calling the abstract class 'CommandBase' seems wrong as well.
So how should I name them?
I would suggest that in your case it is not necessarily bad to name your protocol and the base class the same thing, as your class is the principal expression of the protocol (such as with NSObject).
From Apple's Coding Guidelines for Cocoa: Code Naming Basics:
Some protocols group a number of unrelated methods (rather than create
several separate small protocols). These protocols tend to be
associated with a class that is the principal expression of the
protocol. In these cases, the convention is to give the protocol the
same name as the class. An example of this sort of protocol is the
NSObject protocol. This protocol groups methods that you can use to
query any object about its position in the class hierarchy, to make it
invoke specific methods, and to increment or decrement its reference
count. Because the NSObject class provides the primary expression of
these methods, the protocol is named after the class.
All covered in Apple's Coding Guidelines For Cocoa in the section Code Naming Basics.
The author states:
Protocols should be named according to how they group behaviors:
Most protocols group related methods that aren’t associated with any
class in particular. This type of protocol should be named so that the
protocol won’t be confused with a class. A common convention is to use
a gerund (“...ing”) form:
NSLocking - Good.
NSLock - Poor (seems like a name for a class).
Some protocols group a number of unrelated methods (rather than create
several separate small protocols). These protocols tend to be
associated with a class that is the principal expression of the
protocol. In these cases, the convention is to give the protocol the
same name as the class.
An example of this sort of protocol is the NSObject protocol. This
protocol groups methods that you can use to query any object about its
position in the class hierarchy, to make it invoke specific methods,
and to increment or decrement its reference count. Because the
NSObject class provides the primary expression of these methods, the
protocol is named after the class.
if you will see predefine protocal of uitableview, NSUrlconnection then u will get the name of protocal just like UItabaleviewDelegate and NSUrlconnectionDelegate. ........
Then you can undertand easy which delegate is belong from which class
So u can use your classnameDelegate as protocal name ....thanks
What are those major pro and contra for #protocol and Class Clusters concepts in Objective-C ?
Both of them introduce Loose Coupling in program architecture. Are they conceptually almost equal, or is there something else worth to know ?
Caveat: Not a cocoa pro, but I don't believe they are equal at all.
With Class Clusters you subclass.
Class clusters are a design pattern that the Foundation framework makes extensive use of. Class clusters group a number of private concrete subclasses under a public abstract superclass. The grouping of classes in this way simplifies the publicly visible architecture of an object-oriented framework without reducing its functional richness. Class clusters are based on the Abstract Factory design pattern discussed in “Cocoa Design Patterns.”
#protocols on the other hand, are more like Java interfaces.
The Objective-C extension called a protocol is very much like an interface in Java. Both are simply a list of method declarations publishing an interface that any class can choose to implement. The methods in the protocol are invoked by messages sent by an instance of some other class.
In short, Class Clusters are subclass/superclass where the subclass conforms to the entire identity of the superclass so that the implementation can be hidden from the user. This is apparent in the case of NSArray where the compiler uses context to choose the best type of data structure to use. You don't call NSTree or NSLinkedList like you might in Java. You can see how NSNumber is implemented here, especially the part where it says:
// NSNumber instance methods -- which will never be called...
#protocols are like client/server relationship where the client class adopts a protocol of the server class, so the server can call functionality on the client. <NSAppDelegate> and <UIAlertViewDelegate> are great examples of the use of protocols.
I develop CHDataStructures, a library of Cocoa data structures to supplement those in Foundation. It includes a fair number of classes (stacks, queues, and dequeues) that share common implementation details, so it makes sense to design them with a common parent class which I treat as abstract (Objective-C doesn't natively enforce this concept). For example, CHAbstractCircularBufferCollection encapsulates nearly all the logic for structures that utilize a circular buffer under the covers. Its child classes inherit the core behaviors, and conform to the appropriate protocol so only the methods that pertain to that protocol are added. (So a queue doesn't expose stack methods, etc.)
This has been working just fine, and correctness and coverage are verifiable via unit tests. However, the downside to the current approach is that each concrete subclass has a #import to include the header for the abstract parent class (see this header and implementation) — this means I have to export the parent class headers so client code will compile. It would be ideal if there is a way to use #class in the header rather than #import, so that calling code doesn't have to know or care about the abstract parent class. (It would also simplify and marginally shrink the size of the framework.) However, when I try this:
// CHCircularBufferQueue.h
#import "CHQueue.h"
#class CHAbstractCircularBufferCollection;
#interface CHCircularBufferQueue : CHAbstractCircularBufferCollection <CHQueue>
#end
I get this error, even if I #import CHAbstractCircularBufferCollection.h in the .m file:
Cannot find interface declaration for 'CHAbstractCircularBufferCollection', superclass of 'CHCircularBufferQueue'
I want the compiler to know about the parent class I'm extending, but not require clients to. Is there a way to accomplish what I want to do, and eliminate irrelevant headers from my distribution?
PS - This framework arose mostly from academic curiosity, but I'm considering making changes to make it more like Foundation collections by using class clusters and private subclasses. That would also solve this problem, but I'm curious whether there is a feasible way to do what I'm asking.
If you want to inherit a class, the superclass's #interface (hence the whole superclass hierarchy) must be known so that the ivar offsets of the subclass can be calculated.
You have to #import the .h file for the superclass. As KennyTM points out, this is so the compiler can calculate ivar offsets for the object struct. You can see this in any Cocoa header file. For example, if you open NSArray.h, the very first non-comment line is:
#import <Foundation/NSObject.h>
This holds true for every other class in Cocoa.
Can anyone explain the differences between Protocols and Categories in Objective-C? When do you use one over the other?
A protocol is the same thing as an interface in Java: it's essentially a contract that says, "Any class that implements this protocol will also implement these methods."
A category, on the other hand, just binds methods to a class. For example, in Cocoa, I can create a category for NSObject that will allow me to add methods to the NSObject class (and, of course, all subclasses), even though I don't really have access to NSObject.
To summarize: a protocol specifies what methods a class will implement; a category adds methods to an existing class.
The proper use of each, then, should be clear: Use protocols to declare a set of methods that a class must implement, and use categories to add methods to an existing class.
A protocol says, "here are some methods I'd like you to implement." A category says, "I'm extending the functionality of this class with these additional methods."
Now, I suspect your confusion stems from Apple's use of the phrase "informal protocol". Here's the key (and most confusing) point: an informal protocol is actually not a protocol at all. It's actually a category on NSObject. Cocoa uses informal protocols pervasively to provide interfaces for delegates. Since the #protocol syntax didn't allow optional methods until Objective-C 2.0, Apple implemented optional methods to do nothing (or return a dummy value) and required methods to throw an exception. There was no way to enforce this through the compiler.
Now, with Objective-C 2.0, the #protocol syntax supports the #optional keyword, marking some methods in a protocol as optional. Thus, your class conforms to a protocol so long as it implements all the methods marked as #required. The compiler can determine whether your class implements all the required methods, too, which is a huge time saver. The iPhone SDK exclusively uses the Objective-C 2.0 #protocol syntax, and I can't think of a good reason not to use it in any new development (except for Mac OS X Cocoa apps that need to run on earlier versions of Mac OS X).
Categories:
A category is a way of adding new methods to all instances of an existing class without modifying the class itself.
You use a category when you want to add functionality to an existing class without deriving from that class or re-writing the original class.
Let's say you are using NSView objects in cocoa, and you find yourself wishing that all instances of NSView were able to perform some action. Obviously, you can't rewrite the NSView class, and even if you derive from it, not all of the NSView objects in your program will be of your derived type. The solution is to create a category on NSView, which you then use in your program. As long as you #import the header file containing your category declaration, it will appear as though every NSView object responds to the methods you defined in the catagory source file.
Protocols:
A protocol is a collection of methods that any class can choose to implement.
You use a protocol when you want to provide a guarantee that a certain class will respond to a specific set of methods. When a class adopts a protocol, it promises to implement all of the methods declared in the protocol header. This means that any other classes which use that class can be certain that those methods will be implemented, without needing to know anyting else about the class.
This can be useful when creating a family of similar classes that all need to communicate with a common "controller" class. The communication between the controller class and the controlled classes can all be packaged into a single protocol.
Side note: the objective-c language does not support multiple inheritance (a class can only derive from one superclass), but much of the same functionality can be provided by protocols because a class can conform to several different protocols.
To my understanding Protocols are a bit like Java's Interfaces. Protocols declare methods , but the implementation is up to each class. Categories seems to be something like Ruby's mixins. With Categories you can add methods to existing classes. Even built-in classes.
A protocol allows you to declare a list of methods which are not confined to any particular class or categories. The methods declared in the protocol can be adopted any class/categories. A class or category which adopts a protocol must implements all the required methods declared in the protocol.
A category allows you to add additional methods to an existing class but they do not allow additional instance variables. The methods the category adds become part of the class type.
Protocols are contracts to implement the specified methods. Any object that conforms to a protocol agrees to provide implementations for those methods. A good use of a protocol would be to define a set of callback methods for a delegate (where the delegate must respond to all methods).
Categories provide the ability to extend a current object by adding methods to it (class or instance methods). A good use for a category would be extending the NSString class to add functionality that wasn't there before, such as adding a method to create a new string that converts the receiver into 1337 5P34K.
NSString *test = #"Leet speak";
NSString *leet = [test stringByConvertingToLeet];
Definitions from S.G.Kochan's "Programming in Objective-C":
Categories:
A category provides an easy way for you to modularize the definition of a class into groups or categories of related methods. It also gives you an easy way to extend an existing class definition without even having access to the original source code for the class and without having to create a subclass.
Protocols:
A protocol is a list of methods that is shared among classes. The methods listed in the protocol do not have corresponding implementations; they’re meant to be implemented by someone else (like you!). A protocol provides a way to define a set of methods that are somehow related with a specified name. The methods are typically documented so that you know how they are to perform and so that you can implement them in your own class definitions, if desired.
A protocol list a set of methods, some of which you can optionally implement, and others that you are required to implement. If you decide to implement all of the required methods for a particular protocol, you are said to conform to or adopt that protocol. You are allowed to define a protocol where all methods are optional, or one where all are required.