PDA

View Full Version : Private class methods




KarlJay
Jun 10, 2012, 03:29 PM
In chapter 7 of Learning Cocos2D (Viking game book) It says:
Objective-C does not have explicit support for private class methods: any methods you declare in your header file are considered public methods.

In order to have private methods, you need to include their declarations
in the .m implementation file in an @interface section before the @implementation section.

From what the book is saying, this is an ObjC thing not a Cocos2D thing, which makes sense as Cocos2D is not it's own language.

So, when do you guys actually use Private vs Public methods?
It seems like maybe ObjC only wants you to use public methods because it doesn't directly support private methods.
In fact, this is the 1st book that has actually covered this.



subsonix
Jun 10, 2012, 03:46 PM
A method that is not declared in the @interface, but is implemented in the @implementation is considered private. Utility functions that is not meant to be part of the class interface, but makes the implementation easier/more readable makes sense to hide I think.

jnoxx
Jun 11, 2012, 02:17 AM
For example, when I create alot of methods like - (void) calculateThis, or - (BOOL) isItLikeThis?
I put that in a private interface in the M file. Because you don't want other classes to call it, therefore private. I try to put at least possible methods in my header files as possible, because you want to get the seperation of concern, if you have the same method in several classes, you should foresee utilites classes etc. It's a tad of the MVC pattern + Seperation of Concern.
Hope I made myself clear, not that good in explaining.

Sydde
Jun 11, 2012, 02:47 AM
For example, when I create alot of methods like - (void) calculateThis, or - (BOOL) isItLikeThis?
I put that in a private interface in the M file. Because you don't want other classes to call it, therefore private.

But proceed with caution. Your private methods absolutely must have a unique method signature within the class hierarchy, because all methods are visible to the Objective-C runtime. If you were to write a subclass of some other class that contained private methods, if by chance one of those method signatures matched a method in the superclass, your method would override the superclass, possibly returning an unexpected result.

Somewhat more likely, though, would be a situation where you subclass a class written with private methods: if you inadvertently write a method that matches a private method, when the class calls its private method, it gets your method as an override instead, again possibly yielding unexpected results.

In other words, private methods are for internal use only. It is unwise to publish frameworks containing private methods for others to use unless you also publish the source or are absolutely sure that your classes will never be subclassed.

forum user
Jun 11, 2012, 03:09 AM
What I do is to make public only what can be modified from outside the class without causing problems for the correct functioning on the class. Say the class will provide the result of a calculation and this end result is puplic, the intermediate numbers are not.

Since Xcode 4 (AFAIK) private methods do not need to be declared before usage, but is is a good idea to declare them. The compiler can provide helpful warnings if it can guess what you intend to do.

A typical classes might look like:


// myObject.h
@interface myObject : NSObject

@property (nonatomic, retain) NSArray * arrayResults; // publicly available

/**
* init is public so a class consumer can instatiate it with
* id someObject = [[myObject alloc] init];
*/
-(id)init;

/**
*public method to return a result to the consumer
*/
-(NSNumber*)calculateSomeNumber;


@end


// begin myObject.m ! ===

@interface myObject () // note empty brackets, here do private ivars
@property (nonatomic, retain) NSString * aPrivateString;
@end

@interface myObject (PrivateMethods )
- (NSDecimalNumber*) calculateInbetweenStuff; // here do private methods
@end

@implementation myObject

@synthesize arrayResults;
@synthesize aPrivateString;

- (NSNumber*) calculateInbetweenStuff {
}

@end

Sydde
Jun 11, 2012, 03:29 AM
Since Xcode 4 (AFAIK) private methods do not need to be declared before usage, but is is a good idea to declare them.

C does not actually require you to prototype any functions, and Objective-C works the same way. The compiler reads the implementation file from top to bottom, registering what it finds along the way: any unprototyped (undeclared) function or method can be used by code that is below it in the file. But that is typically an awkward way to compose, and it can be hard to read.

jnoxx
Jun 11, 2012, 04:00 AM
Before the latest versions of Xcode, it would also generate a warning that this method is not declared, but it would work.
And you write a double interface, I mostly just put it all in one..

@interface PictureViewController ()
{
UILabel *countDownLabel;
int countdown;
BOOL isLastPic;

NSMutableArray *pictureArray;
}

@property(nonatomic, strong) AVCaptureStillImageOutput *stillImageOutput;

- (void) someRandomMethod;
@end


Same as you would declare your header. But this is personal taste, I like your approach too.

forum user
Jun 11, 2012, 05:38 AM
It is some form of "evolution in progress". When I looked at my, lets say old style, dot-h files I regularly became confused as to which method is private and which ones are public. Same with the ivars: for which did I declare properties which ones are still missing.
So I refractored the file pair to the format above. It works fine for my needs, but then: my needs are not everybody needs :)

PhoneyDeveloper
Jun 11, 2012, 06:54 PM
@forum_user, what you show is a class extension and a category. Good form would be to use only the class extension.

It seems that with the latest Xcode an empty class extension is added at the top of New .m files.

forum user
Jun 12, 2012, 07:29 AM
I learned long time ago that I am no code poet, so I gave up on good form. ;)

A category as such will extend a class by publicly declared methods in the header file. We wanted private methods.
Moving the declaration to the implementation file will keep the methods declaration private. The compiler has visibility of the (private) declaration and can raise warning if the actual implementation is incorrect. A double benefit.

Strictly speaking the PrivateMethods could go into a separate file. In that case we would have the public interface in the header file, the implementation file and the file with the private methods. But that would increase the number of files to maintain.