4
votes

Due to the circumstances of what I'm programming, I need to implement some methods in a class without actually editing the class, so I am using categories.

The trouble is there are methods not included in the interface of the class, but are implemented in the class implementation. I'm assuming this just means they are private methods.

Is it not possible for a category to have access the private methods of its main class? When I try to use one of the private methods in my category I get the error:

"No visible @interface for 'MainClass' declares the selector 'privateMethod'"

This is understandable because it isn't in the interface, but I thought it would logically make sense that I'd be able to access everything in the implementation.

2

2 Answers

5
votes

The methods you want to call need to be declared somewhere. You can declare them yourself using your own category:

@interface MainClass(MyPrivateMethods)
- (CGRect)privateMethod:(NSString*)someParameter;
@end

That will get rid of the "No visible @interface for 'MainClass' declares the selector" compiler warning, and you just have to hope that it works at runtime. If MainClass does not have a method by that name with those parameter and return types then it will fail at runtime.

(You can also use performSelector: but you may still get warnings about unrecognized selectors, depending on your compiler settings, and doesn't work with all parameter and return types).

2
votes

There is a standard way of handling this.

@interface MainClass ()
- (void)privateMethod;
@end

If you only need access to the methods in 1 .m file, then place the declaration at the top of that file. If you need access in more than 1 .m file, then create a MainClassSubclass.h header to hold these methods.

For an example of this pattern, look at UIGestureRecognizerSubclass.h in UIGestureRecognizer


In effect, you are turning your private method in to a protected method.