This isn’t a style question. Its more about the proper use of the language itself. I’m am fairly new to programming and I’m totally new to Objective-C and Cocoa but after reading about the language and looking through some sample code some usage patterns continue to pop up that do not make sense to me. Or rather they seem non optimal in my mind. I am hoping you all can help educate me in the proper uses of some of these language constructs.
interfaces vs protocols
I understand the concepts of interfaces and implementation as they relate to abstraction. However the dominant pattern I see in Objective-C sample code is the following…
@interface Foo : NSObject
{
some ivars decls
}
some methods decls
@end
And then client code in the form of…
Foo* f = [[Foo alloc] init];
This seems odd to me. Foo seems to be an implementation in my mind (irregardless of the unfortunate naming of the @interface keyword). Interfaces in my mind do not expose instance variables. A client of this class should not be exposed to the details of my implementation.
Objective-C does have the @protocol keyword which in my mind is more of an interface than the @interface keyword. It allows you to define the methods and/or properties and that’s it. No implementation. No instance variables. Just interface.
@protocol Foo <NSObject>
some methods
maybe some properties
@end
@interface FooProvider : NSObject
+ (FooProvider*) sharedProvider;
- (id<Foo>) fooWithBlahBlah;
@end
So the client code would take the form of…
id<Foo> f = [[FooProvider sharedProvider] fooWithBlahBlah];
[f whatever];
This seems (at least to me) to be a more abstract usage of the language and isolates clients from implementation details they aught not to be dependent on. My question is which should I be striving to follow. I understand that there may be situations where one is preferable over the other but in general terms should one be the norm and one be the exception?
Some guidance would be appreciated.
Thanks,
Roman
I can see where you are coming from in regards to the naming of the
@interfacekeyword, but Objective-C uses the two keywords@interfaceand@implementationto differentiate between the class declaration (interface) and its definition (implementation). The@interfaceportion is usually placed in the class header file, and the@implementationportion goes in the source file. I agree with you 100% that the internal instance variables really shouldn’t appear in the header file. I’m not sure what led to that decision, but my best guess is that it has to do with object inheritance. When you inherit from a parent class:You also inherit all of the instance variables, which would be very difficult for the compiler to figure out unless those variables are declared in the class header.
You are also correct about the usage of
@protocol, in that it essentially defines an interface that a class must adhere to. Protocols appear to be Objective-C’s answer to multiple inheritance.In my experience with Objective-C, protocols are not used very often. They have their place, but the majority of the code uses the basic
@interfaceand@implementationkeywords to define a class, and protocols are only used when some extra functionality is required that doesn’t quite belong in the class hierarchy, but still needs to be shared across multiple classes.If you’re looking for guidance, I would say:
@interfaceand@implementationkeywords, even if it doesn’t quite jive with what you expect. When programming in Objective-C, drink the Kool-Aid and see those keywords the way the language designers intended.