Search code examples
objective-cinheritancepropertiesivar

Better way to declare properties as protected


Following this blog post, I saw a way to solve the problem I was facing.

My problem, like his, was that I have a class that has a property which must be inherited and accessed in its subclass:

@interface A : NSObject
@property (nonatomic, readonly) NSUInteger prop;
@end

@implementation A
    // Don't need to synthesize nowadays
@end

@interface B : A
    // No new properties
@end

@implementation B

- (void)establishValueForProp
{
    _prop = 1; // PROBLEM !!!
}

@end

The solution was this:

@interface A : NSObject {
    @protected
    NSUInteger _prop;
}
@property (nonatomic, readonly) NSUInteger prop;
@end

What I'm wondering is if there is another way to declare properties as protected?


Solution

  • Another common way of doing it, is by creating a separate .h file (ASubclass.h, for example) and adding something like this:

    @interface A (Protected)
    
    @property (nonatomic, readonly) NSUInteger prop;
    
    @end
    

    Subclassers can then import this .h and will have access to this method. Note that since categories can't add properties, you'll have to redefine this property in A's private interface (class extension). The category will then provide public access to this property. Apple takes this exact approach with UIGestureRecognizer.h and UIGestureRecognizerSubclass.h (where UIGestureRecognizer.h exposes more methods, intended for subclassers to override).

    The concept of protected (or private, for that matter) methods doesn't really exist, and this is only a way to somewhat achieve similar functionality.

    Personally, I just create a category in the (only) .h file of the class that exposes an otherwise public property. This way it's separated from the main public interface, and since it's possible to get to private properties anyway, I think this approach is good enough.