siutsin
siutsin

Reputation: 1624

How to override private method and property from superclass in objective c

Using libraries from cocoapods, I want to override some private methods without messing up the library.

ClassInLibrary.h

@interface ClassInLibrary : UIView     
- (void)publicMethod;
@end

ClassInLibrary.m

@interface ClassInLibrary ()   
@property BOOL privateBoolean;   
@end   
@implementation ClassInLibrary  
- (void)privateMethod {
    ...
}
- (void)publicMethod {
    ...
    self.privateBoolean = YES;
    [self privateMethod];
}    
@end

What I am trying to do is create a subclass of ClassInLibrary and override the publicMethod. However, as aBoolean and privateMethod are not visible, are there any ways to override publicMethod as I need to use them?

Subclass.m

@interface Subclass ()    
@end    
@implementation Subclass
- (void)publicMethod {
    ...
    self.privateBoolean = NO; // cannot access
    [self privateMethod]; // cannot access
}   
@end

EDIT:

I agreed with @Anoop Vaidya, it is not a good idea to call private API. The real case is a hardcoded string in the public method and I want to modify it.

Superclass.m

- (void)publicMethod {
    ...
    [self privateMethod];
    ...
    NSString *string = @"a string";
    [self doSomeThingWithTheString]; // private
    ...
} 

I can't use the [super publicMethod] as it will call the privateMethod again. May be there are better and safer approaches to achieve this?

Upvotes: 4

Views: 4143

Answers (2)

Anoop Vaidya
Anoop Vaidya

Reputation: 46563

You can do as below, but you should not do.

You can call the private method by using selectors, but it will show you a warning which you can disable.

    SEL selector = NSSelectorFromString(@"privateMethod");
    if ([a respondsToSelector:selector]) {
        NSLog(@"yes privateMethod exists");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [self performSelector:selector];
#pragma clang diagnostic pop
    }

Upvotes: 4

Wain
Wain

Reputation: 119031

You can use a category, defined in your subclass, but on the superclass, to make the property and method definition visible to the subclass. Now you can override the public method and use the private parts.

You still need to be careful as, if the private parts are changed / moved / renamed in the future your code will compile just fine. So, when doing this kind of thing your code should be defensive and generate good meaningful errors so you know what happened. Also ensure that this area is covered by unit / regression tests.

Upvotes: 2

Related Questions