PDA

View Full Version : How can I call private methods of a superclass without getting a compiler warning?




Nutter
Dec 21, 2006, 10:14 PM
I hope this isn't a silly question.

Let's say I have a class Foo, implemented in Foo.m like this:


@interface Foo (Private)
- (void)_doPrivateBlah;
@end

@implementation Foo
- (void)doBlah; {}
@end

@implementation Foo (Private)
-(void)_doPrivateBlah; {}
@end


How can I call _doPrivateBlah from a subclass of Foo without getting a compiler warning?

If I add #import "Foo.m" to my subclass' implementation file, it works fine in debug mode but I get an error when compiling in XCode with the standard release configuration. The error is as follows:


multiple definitions of symbol .objc_category_name_Foo_Private
multiple definitions of symbol .objc_class_name_Foo
Command /usr/bin/gcc-4.0 failed with exit code 1


This is fair enough. Still, I'm now at a loss as to how I can get rid of those annoying warnings... Can anybody help?



kainjow
Dec 21, 2006, 10:43 PM
You can redeclare it in your subclass, before your @implementation in your .m file:

@interface Foo (Private)
- (void)_doPrivateBlah;
@end

@implementation MyFooSubclass

...

Or use selectors:

[self performSelector:@selector(_doPrivateBlah) withObject:nil];

Nutter
Dec 21, 2006, 10:56 PM
Thanks a lot for your help, kainjow.

robbieduncan
Dec 22, 2006, 04:02 AM
If it's your own code I think you should be able to import the .h file with the private methods into the .m file of the subclass. I've not tried it but I think it should work.

gnasher729
Dec 22, 2006, 06:42 AM
That is what private methods are there for: They can only be called from within a class. Someone made that made private to _prevent_ what you want to do.

Change the methods to "protected" if you need to call them from a derived class, or to "public" if you need to call them from the outside. However, if you think you need to call a private method, then either you are making a mistake or the designer of the superclass made a mistake. First find out why that method is private.

robbieduncan
Dec 22, 2006, 07:01 AM
That is what private methods are there for: They can only be called from within a class. Someone made that made private to _prevent_ what you want to do.

Change the methods to "protected" if you need to call them from a derived class, or to "public" if you need to call them from the outside. However, if you think you need to call a private method, then either you are making a mistake or the designer of the superclass made a mistake. First find out why that method is private.

In Java that's true. In Obj-C there is no language level protection. If you know the name of the method you can call it. The only protection is not to declare the method in the public header for the class. As we have categories we can declare our private methods in a (Private) category and happily call them ourselves by importing that header into our implementation class whilst hiding the name from others. But you can class dump the class to get the names and call them anyway.

Nutter
Dec 22, 2006, 09:29 AM
If it's your own code I think you should be able to import the .h file with the private methods into the .m file of the subclass. I've not tried it but I think it should work.

I've declared and implemented the private category in my ".m" file (as per my example), so I can't do this.

I suppose I could put the interface of this category into a separate ".h" file. That may indeed be the most elegant solution.