Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expose a private Objective-C method or property to subclasses

According to some official talk, a class in Objective-C should only expose public methods and properties in its header:

@interface MyClass : NSObject  @property (nonatomic, strong) MyPublicObject *publicObject;  - (void)publicMethod;  @end 

and private methods/properties should be kept in class extension in .m file:

@interface MyClass()  @property (nonatomic, strong) MyPrivateObject *privateObject;  - (void) privateMethod;  @end 

and I don't think there is a protected type for things that are private but accessible from subclasses. I wonder, is there anyway to achieve this, apart from declaring private properties/methods publicly?

like image 280
hzxu Avatar asked Sep 28 '12 04:09

hzxu


People also ask

Do subclasses have access to private methods?

A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass. A nested class has access to all the private members of its enclosing class—both fields and methods.

How do you make a private method in Objective C?

To avoid exposing a method as part of a class's API, we do not declare it within the @interface section but within the @implementation section. Now, a private method like makeActivationSound can no longer be called by another class. A method call from a Jedi class like… [[Lightsaber new] makeActivationSound];

When should I use subclass?

Subclassing : If we want to modify state as well as behaviour of any class or override any methods to alter the behaviour of the parent class then we go for subclassing. For example : We subclass UIView to alter its state and behaviour in our iOS code. Save this answer.

What is Property OBJC?

The goal of the @property directive is to configure how an object can be exposed. If you intend to use a variable inside the class and do not need to expose it to outside classes, then you do not need to define a property for it. Properties are basically the accessor methods.


1 Answers

One way to solve this is to re-declare the property in your subclass's class extension, and then add an @dynamic statement so that the compiler won't create an overriding implementation of that property. So something like:

@interface SuperClass ()  @property (nonatomic, strong) id someProperty;  @end  ....   @interface SubClass ()  @property (nonatomic, strong) id someProperty;  @end  @implementation SubClass  @dynamic someProperty;  @end 

This obviously isn't ideal because it duplicates a privately visible declaration. But it is quite convenient and helpful in some situations so I'd say evaluate on a case-by-case basis the dangers involved in this duplication vs. exposing the property in the public interface.

An alternative - that is used by Apple in UIGestureRecognizer - is to declare the property in a separate category header file explicitly named as "private" or "protected" e.g. "SomeClass+Protected.h". That way, other programmers will know they ought not import the file. But, if you don't control the code you're inheriting from, that's not an option.

like image 93
Carl Veazey Avatar answered Sep 28 '22 23:09

Carl Veazey