Objective-C: Compiler error when overriding a superclass getter and trying to access ivar

前端 未结 2 1507
旧时难觅i
旧时难觅i 2020-12-15 21:32

I\'m working on building an iOS 6 app.

I have a class TDBeam which inherits from superclass TDWeapon.

The superclass

相关标签:
2条回答
  • 2020-12-15 22:12

    There are a lot of posts on this topic on Stack Overflow, none of which offer simple concrete advice, but this topic sums it up most succinctly, and Josh's answer is the best in any.

    What he kinda stops short of saying outright, is, if this is the kind of thing you want to do, don't use @property at all. Declare your regular protected variable in your base class as he says, and write you're own setters and getters if you need them. The ivar will be visible to any subclasses who can then write their own setters/getters.

    At least that's where i've landed on the issue, although I'd a total newb to subclassing.

    The idea of creating private headers to host your anonymous category and re-@sythesizing your ivars in your subclass just seems wrong on so many levels. I'm also sure I've probably missed some fundamental point somewhere.


    Edit

    Okay after some lost sleep, and inspired by Stanford's 2013 iTunes U course, here I believe is an example solution to this problem.

    MYFoo.h

    #import <Foundation/Foundation.h>
    
    @interface MYFoo : NSObject
    // Optional, depending on your class
    @property (strong, nonatomic, readonly) NSString * myProperty;
    - (NSString *)makeValueForNewMyProperty; //override this in your subclass
    @end
    

    MYFoo.m

    #import "MYFoo.h"
    
    @interface MYFoo ()
       @property (strong, nonatomic, readwrite) NSString * myProperty;
    @end
    
    @implementation MYFoo
    // Base class getter, generic
    - (NSDateComponents *)myProperty {
        if (!_myProperty) {
            _myProperty = [self makeValueForNewMyProperty];
        }
        return _myProperty;
    }
    
    
    // Replace this method in your subclass with your logic on how to create a new myProperty
    - (NSString *)makeValueForNewMyProperty {
        // If this is an abstract base class, we'd return nil and/or throw an exception
        NSString * newMyProperty = [[NSString alloc]init];
        // Do stuff to make the property the way you need it...
        return newMyProperty;
    }
    
    @end
    

    Then you just replace makeValueForNewMyProperty in your subclass with whatever custom logic you need. Your property is 'protected' in the base class but you have control over how it is created, which is basically what you are trying to achieve in most cases.

    If your makeValueForNewMyProperty method requires access to other ivars of the base class, they will, at the very least, have to be be public readonly properties (or just naked ivars).

    Not exactly 'over-ridding a getter' but it achieves the same sort of thing, with a little thought. My apologies if, in trying to make the example generic, some elegance and clarity has been lost.

    0 讨论(0)
  • 2020-12-15 22:19

    Synthesized ivars are not visible to subclasses, whether they are explicitly or automatically created: What is the visibility of @synthesized instance variables? Since they are effectively declared in the implementation file, their declaration isn't included in the "translation unit" that includes the subclass.

    If you really want to access that ivar directly, you'll have to explicitly declare it (in its default "protected" form) somewhere that the subclass can see it, such as a class extension of the superclass in a private header.

    0 讨论(0)
提交回复
热议问题