Why does this code example on Apple's dev site declare three interfaces for the same class? - iphone

I'm diving into iOS development while trying to grasp Objective-C and I'm still in that phase where, ever where I look, I see things that don't make any sense to a veteran C programmer like myself. In this Game Kit example on Apple's dev site, one of the header files declares a class interface, three different times...
#interface SessionManager : NSObject <GKSessionDelegate> {
NSString *sessionID;
GKSession *myGKSession;
NSString *currentConfPeerID;
NSMutableArray *peerList;
id lobbyDelegate;
id gameDelegate;
ConnectionState sessionState;
}
#property (nonatomic, readonly) NSString *currentConfPeerID;
#property (nonatomic, readonly) NSMutableArray *peerList;
#property (nonatomic, assign) id lobbyDelegate;
#property (nonatomic, assign) id gameDelegate;
- (void) setupSession;
- (void) connect:(NSString *)peerID;
- (BOOL) didAcceptInvitation;
- (void) didDeclineInvitation;
- (void) sendPacket:(NSData*)data ofType:(PacketType)type;
- (void) disconnectCurrentCall;
- (NSString *) displayNameForPeer:(NSString *)peerID;
#end
// Class extension for private methods.
#interface SessionManager ()
- (BOOL) comparePeerID:(NSString*)peerID;
- (BOOL) isReadyToStart;
- (void) voiceChatDidStart;
- (void) destroySession;
- (void) willTerminate:(NSNotification *)notification;
- (void) willResume:(NSNotification *)notification;
#end
#interface SessionManager (VoiceManager) <GKVoiceChatClient>
- (void) setupVoice;
#end
I see that each interface is different, but specify the same class name.
What's the reason for this?
I've also noticed this same behavior in other code examples, only instead of declaring multiple interfaces in the header file, you'll see an additional #interface block declared towards the top of the .m implementation file, typically above the #implementation block. Why?
Thanks so much in advance for your wisdom!

These are called Categories, and you can see them by the parentheses after the class name.
They're used to group methods into chunks instead of having them all in one big bunch. They can also be placed separate from the main class declaration. This is particularly useful inside .m files, where you may need to create utility methods for your class, but you don't want them visible to other objects for any reason (so you don't put them in the .h, which is imported by the other classes). Another common use is to group methods which correspond to a certain logical category, informal protocol, or what have you. Categories can be named (#interface MyClass (MyCategory)) or anonymous (#interface MyClass ()). The latter is usually used for generic private methods in your header.
(The reason you need categories to declare private methods in your .m is so the compiler knows about the methods — otherwise, you'll get a warning when you try to call such a method.)
Also, you can use categories to add methods to existing classes. For example, UIKit contains a category on NSString called NSString(UIStringDrawing). Or if you wanted to make your own:
#interface NSString (MyFoo)
+ (NSString *)fooString;
#end
//... somewhere else...
#implementation NSString (MyFoo)
+ (NSString *)fooString { return #"foo!"; }
#end
Note that you can't add instance variables with a category.

It is not defining the interface 3 times - there is only one interface.
what you are seeing are categories that add methods to the class
There is a base interface that defines the attributes and some methods - there is only one of these ant it defines how the object is stored in memory and is the only one that is needed.
Objective C looks up methods at run time. These methods do not need to be found at compile time and thus do not need to be declared in headers/interfaces etc. If they are not declared and you code calls them then you will get compile time warnings.
In this case one category with an empty name is used for private functions. I usually only put this interface in the .m file of the class so is not visible to other code as not in a header.
The second category is to add the methods to make SessionManager meet the GKVoiceChatClient protocol. The usual reason for doing this is to group code covering a specific behaviour together.
Another reason for using categories is to add methods to an existing class like NSString -you can create your own category adding methods without subclassing the class as you have to do in many other OO languages including Java and C++

This is for code upkeep purposes i belive...its easier to looks through the different labeled interfaces, for example (VoiceManager) which is for voice manager setup and methods related to that, and you have the one interface dealing with the GK delegate methods and whatever interaction with gamekit there will be...as opposed to looking at one huge interface file and having to pick out what you are looking for...They can also divide the implementations in this way too so its easier to look through and navigate.

In order:
The first interface declaration is the actual interface declaration that declares the class as a subclass of NSObject and implementing the GKSessionDelegate protocol. It also declares the instance variables and a selection of methods.
The second interface declaration is a class extension. It can be thought of as a kind of anonymous category. So we'll skip it for now and come back to it.
The third interface is a category declaration. Categories allow you to do two things. They allow you to split the class implementation across multiple source files. In the above, you'll have
#implementation SessionManager
// methods declared in the first #interface
#end
#implementation SessionManager(VoiceManager)
// methods declared in the third #interface
#end
The two #implementations need not be in the same source file.
The other thing a category can do is allow you to extend already existing classes.e.g. #interface NSString(MyStringMethods)...
Coming back to the class extension, this is a bit like an anonymous category. The implementations of the methods declared in it must be in the main #implementation block. The purpose of the class extension is to allow you to declare private API separately from the class's header file. I normally put one in the.m file at the top if I have methods that should only be used from the class. Although, note that this is only a compile time restriction. There is nothing to stop a class extension message from being sent by anybody at run time.

Related

Objective-C Package level Property

I am creating an iPhone custom framework which should be able to be integrated into any iPhone app.
I have created some properties in one of the public header files of my framework. I want to give #package level access to those properties, so that those properties can be accessed only with in the classes inside the framework.
I do not want the user to use those properties.
Please tell me whether doing this is possible. If yes, please give me some idea on how to achieve this!.
First you should know that there is no way to completely forbid a user of your library to call a method. Even if you don't declare it in your header, a user could declare it on its own and use it. He would still have to find out the name of your property though, for instance by running classdump on your library.
Therefore in Objective-C, we make properties private by not declaring them in the header (which is the public part of your class), but by declaring them in the implementation (which is the "private" part of your class).
If you create another header which contains a category on your class, you can add some properties to it that will not be in the main header - so not on the public declaration of your class - but that can still be imported by other classes of your library that know about this header.
For instance:
MyClass+SecretProperties.h:
#interface MyClass ()
#property (strong) NSString *secretString;
#end
MyClass.m:
#import "MyClass.h"
#import "MyClass+SecretProperties.h"
#implementation MyClass
#synthesize secretString; // Depending on your runtime, you may not even need to this - properties are auto-synthesized in the latest SDKs.
…
#end
OtherClass.m:
#import "MyClass.h"
#import "MyClass+SecretProperties.h"
// Now you can use secretString on instances of MyClass
Then since you only export MyClass.h with your library, users have no idea that there is a secretString property :) This is the closest you can get to a #package scope AFAIK.
If you want to make those property as private then use below things.
In your .m file use extension characteristics of objective c.
#interface InitialViewController ()
//declare your property here
#end

Extensions/Categories instead of Interface

So I noticed that in my new Xcode projects, by default there was a category for my class in my .m file. For example, I'll have this in the .m file:
#interface ViewController ()
#end
#implementation
//Some code
#end
I was wondering is it okay to declare my variables and functions in the category in the .m file, or should I do that in the .h file like before. Basically, what are the best practices in respect to categories.
By the way, my question is sort of related to the below link, but that link does not completely answer my question.
This is not a category, it is a class extension (notice the empty parentheses). You can keep private implementation details, including private ivars, in the extension to limit the declarations in the .h file to the interface of your class. Note that you can add ivars only in the extensions, not in categories.
One very important consequence of this approach is that if you need ivars of types that require additional headers needed only for implementation, you can avoid including that header in the header of your interface, hiding implementation dependencies from users of your class.

Objective-C when to declare what methods in #interface

When and what methods should be declared in the #interface section of a class? As I understand, methods that describe what your class does should be declared in the #interface section, but other "helper" methods should not be declared. Is this a correct understanding from my side?
One way is to declare the instance methods in .h file. And, declare the private methods inside the .m, using a Category.
For example, in MyOwnClass.h file.
#interface MyOwnClass
- (void)aInstanceMethod;
#end
And, inside your MyOwnClass.m file, before the #implementation block,
#interface MyOwnClass (MyPrivateMethods)
- (void)aPrivateMethod;
#end
You usually should add your methods to the .h file when you want an external class to have access to it (public methods).
When they're private (only used internally by the class) just put them in your .m file.
Anyway, it's just a pattern. As Objective-C works with messages, even if you don't set a method in your .h file an external file can access it, but at least your auto-complete won't show it.
You should declare all your methods in your .h
The tip from EmptyStack is nice but it's just a tip.
If you don't intend to ship your binary as an SDK, you don't really need it.
Objective-C doesn't have (yet) private methods.

How to set up non-instantiated classes in Objective-C (Classes with just methods)

I'm looking to create a class in Objective-C for an iOS project that is focused on fetching data. I'm familiar with how classes normally work, setter and getter methods and variables. However, for this class since it's only performing a function (returning NSMutableArrays) I don't want to have to create an instance of the class to use the methods inside the class.
Any idea how I can do this neatly and efficiently?
This is a little bit atypical in Objective-C. Since classes in Objective-C can't actually have state beyond what is available to ordinary functions (i.e. there are no class variables), a class that's never instantiated is relatively useless in most cases. The normal design patterns for this kind of functionality are:
A singleton class (if you need lots of state)
A set of functions (if you don't)
You want to make class methods?
#interface Foo : NSObject {}
+(NSMutableArray*)someClassMethod:(id)params;
#end
...
#implementation Foo
+(NSMutableArray*)someClassMethod:(id)params {
// whatever implementation
return nil;
}
#end
...
NSMutableArray* array = [Foo someClassMethod:nil];
If you're only performing functions, and you don't need to support subclassing etc, why not just write them as C functions rather than a class with methods?
If this is just a class that performs some functions, you could write it as a C function.
In your header file --
NSMutableArray *functionThatReturnsMutableArray(NSObject *param1, NSString *param2);
In your implementation file --
NSMutableArray *functionThatReturnsMutableArray(NSObject *param1, NSString *param2)
{
...
return aMutableArray;
}
And that just include the .h file in your class that needs these functions and call them directly.
NSMutableArray *anArray = functionThatReturnsMutableArray(param1, param2);
Depending on what you are doing (the same NSString operations, UIView manipulations, etc), you could implement a category (I answered a question yesterday with the explanation below -- copied for your convenience ;).
Categories extend an existing class with additional methods or with your version of existing methods. For example, let's say you want to add a method that returns the first letter of a string to NSString. To do this you would create a category as follows:
Interface - JULString.h
#import NSString
#interface NSString (JULString)
-(NSString *) firstLetter;
#end
Implementation - The typical convention is that the filename of the category is the name of the class you are extending followed by “+” and the name of the category. In this case the file would be called NSString+JULString.m
#import "NSString+JULString.h"
#implementation NSString ( JULString )
- (NSString *)firstLetter
{
return [NSString stringWithFormat:#"%C", [self characterAtIndex:1]];
}
#end
The neat thing about categories is that now they extend the behavior of ANY instance of the class you are working with. In other words, any NSString in your application will have your new methods (provided that you import the proper header file of course). Beware though, as with great power comes great responsibility. Overwriting class using a category behaviors may lead to undesired effects, so be cautious.
A couple of links you may want to check are:
Apple's guide to Objective-C
Learn Objective-C
Note:
I don't have my Mac with me so I'm writing this code basically off the top of my head (and using some code from the sites above as a reminder). So I apologize in advance for any mistakes ;)

Cocoa Interface Style

I'm on a project doing an iPhone application. We had a Cocoa consultant come in for a few weeks. He showed me an interesting idiom of Cocoa, dealing with interfaces, but there was a difficult language barrier between us, and he wasn't really able to explain why this was done or where it was documented so I could learn more on my own. I went into monkey see mode, and just used the style he prefers. But it's been bugging the hell out of me that I don't know more about the history of this style. It's certainly NOT an informal protocol. Sure enough, looking at some of the Cocoa API headers, I sometimes see the style he asserted was the 'Cocoa' way. Here's an example (note accessors, mutators, etc., each have their own interface declaration without the funny braces):
#interface AViewController : UIViewController <UITextViewDelegate> {
#public
UITableView *tableView;
#private
NSUInteger someIndex;
}
#property (nonatomic, retain) ...
#end
#interface AViewController (AViewControllerCreation)
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil withController:(id)controller;
#end
#interface AViewController (AViewControllerMutator)
- (void) doSomeSettingStuff;
#end
#interface AViewController (AViewControllerAccessor)
- (NSString *)doSomeAccessorStuff;
#end
#interface AViewController (AViewControllerAction)
- (IBAction)cancel:(id)sender;
#end
#interface AViewController (AViewControllerTableViewDelegate) <UITableViewDelegate, UITableViewDataSource>
#end
You can see this style of setting up the interface in NSButton, NSControl, etc. Interestingly, corresponding classes like UIButton, UIControl DON'T use this idiom. Hmm, these probably came after as I assume UIKit was done after AppKit. So is this idiom 'old hat'? Also, is there any reason for it other then style? Is it good style? Bad? Any docs that go over this? Thanks all.
These are what's known in Objective-C as "categories". Categories make it possible to have multiple #interface and #implementation blocks for the same class. This works even to the extent that you can add methods on classes in the standard Apple frameworks, e.g. adding a category on NSString to add new methods to it. Categories can add methods but not instance variables, so in your example the first #interface is the core class declaration and all of the others are categories on the AViewController class.
It's not "old hat" by any means but your example takes the use of categories to a rather bizarre extreme. Categories make sense wherever it makes logical sense to break up a class's implementation into multiple blocks, for example if the class has a bunch of methods that logically fall into two or more groups. They're also sometimes used to declare pseudo-private methods by putting a category #interface named "private" in the same file as the #implementation. ObjC's dynamic dispatch means there's no such thing as a private method but this approach avoids publishing the names of methods you'd prefer people not to use.
The example above is not actually wrong but it's kind of ridiculous. It suggests that the contractor got the idea that every new method should always have its own category for some reason, which is just not true.
That example is very strange and would definitely raise a red flag for any experienced Cocoa programmer.
It is a common practice to use categories in the same way to separate private methods from the public implementation, and I've done the same thing in the past to separate private threaded methods from code that runs on the main thread. I can't see any good that would come from separating out all your public methods like that though.
What is a good tool for this situation is the #pragma mark <label> keyword. which allows you to group similar methods in an implementation. I think that's what you're aiming for, although you don't need to go overboard in creating groups. For example, in a window controller class I would have #pragma mark API, #pragma mark NSWindowController Overrides, #pragma mark NSObject Overrides, #pragma mark NSWindow Delegate Methods, and so on. That helps me find and jump to the method I'm looking for very quickly in Xcode, although it's just a matter of style so you can really use it however you see fit.
One really good reason for having a public category, and one that Apple uses often, is for extending a class with functionality that exists in the category's framework, but which doesn't exist in the framework that defines the class. For example, NSString is defined in Foundation.framework, but categories on NSString defining methods for drawing an NSString to the screen are defined in AppKit.framework.
Another good usage of categories is for dependency hiding; e g if you really need boost for a part of the class, you can have that in a separate header and implementation file, and a user of the class that needs the boost parts can import that header together with the one originally defining the class, and only that file will take ages to compile. This is more useful in the 64-bit runtime, where a category can add instance variables.
A really large implementation over several source files (but a single header) is also a good candidate, as Tom points out :)
I'd just like to add to Tom's original answer: Generally, it's better to use a class extension than a class category when declaring private methods. This way, you can implement the extension in the same #implementation block as the public methods, without getting a warning about "missing category implementation". Example:
// .h file
#interface Foo : NSObject
-(void)publicMethod;
#end
// .m file
#interface Foo ()
// Notice the empty paren; this is how you define
// a class extension, which is not the same as a category
-(void)somePrivateMethod;
#end
#implementation Foo
#pragma mark Public methods
-(void)publicMethod;
{ ... }
#pragma mark Private methods
-(void)privateMethod;
{ ... }
#end
I don't know; those look a lot like informal protocols to me, largely for delegates. See pages 297 - 298 of Cocoa Programming with Mac OS X, 3rd Edition. The protocols are implemented via Categories ... And in all honesty, they appear to be heavily overused in your sample.
Regarding John Rudy's response-- It's true that informal protocols are implemented as categories, but they're generally categories on NSObject. Since the informal protocol might be used by almost any object, it needs to be a category on an class that the adopting object inherits from, and pretty much everything is going to inherit from NSObject. You could make a case for an informal protocol as a category on some other class in specific situations, but it's an unusual approach and definitely not "the Cocoa way"
Ok, I believe Tom's answer is the most useful so far. However, as everyone seems to think this an overboard use of categories I again took a look at NSButton. Below is a bastardized version of the header:
#interface NSButton : NSControl <NSUserInterfaceValidations>
- (NSString *)title;
- (void)setTitle:(NSString *)aString;
...
...
#end
#interface NSButton(NSKeyboardUI)
- (void)setTitleWithMnemonic:(NSString *)stringWithAmpersand;
#end
#interface NSButton(NSButtonAttributedStringMethods)
- (NSAttributedString *)attributedTitle;
- (void)setAttributedTitle:(NSAttributedString *)aString;
- (NSAttributedString *)attributedAlternateTitle;
- (void)setAttributedAlternateTitle:(NSAttributedString *)obj;
#end
#interface NSButton(NSButtonBezelStyles)
- (void) setBezelStyle:(NSBezelStyle)bezelStyle;
- (NSBezelStyle)bezelStyle;
#end
#interface NSButton(NSButtonMixedState)
- (void)setAllowsMixedState:(BOOL)flag;
- (BOOL)allowsMixedState;
- (void)setNextState;
#end
#interface NSButton(NSButtonBorder)
- (void) setShowsBorderOnlyWhileMouseInside:(BOOL)show;
- (BOOL) showsBorderOnlyWhileMouseInside;
#end
#interface NSButton (NSButtonSoundExtensions)
- (void)setSound:(NSSound *)aSound;
- (NSSound *)sound;
#end
So if their using categories to organize NSButton into sections: (NSButtonMixedState) (NSButtonBorder) above, that really only have a couple of operations, why is using this for organizing accessors/mutators bad style? Of course my first example was a silly pedantic interface, but the intent of separating groupings of operations is the same.
First of all, just because something appears in one of Apple's header files doesn't necessarily mean you should take it as an example of a good way to do things. Apple's developers are human too, and subject to the same limitations of skill and time pressures as anyone else.
Using multiple categories in this way suggests that NSButton's implementation is divided into several source files. This might be because the different aspects of NSButton were coded by different people, or at different times, or possibly some other reason. Regardless the division is likely based in part on how the development team and its processes are organized, with the category system providing a way for the work to be divided. In the ideal setup you'd break things up on logical functional boundaries but in practice other factors can come into play.