Objective-C: How do you access parent properties from subclasses?

后端 未结 5 941
失恋的感觉
失恋的感觉 2020-12-04 16:28

If I have this class defined, how do I access the someObject property in subclasses without compiler errors?

@interface MyBaseClass
  // someObj         


        
相关标签:
5条回答
  • 2020-12-04 16:59

    that's how you access them. how you declare them is what's biting you:

    @interface MyBaseClass : NSObject
    @property (nonatomic, readwrite, retain) NSObject *someObject;
    @end
    

    this is the normal way to declare a new objc class.

    by adding the parentheses (instead of declaring the superclass - NSObject in this case), you have declared a class extension, which is probably not visible to the subclass (via inclusion).

    you will probably never need to declare a root class in objc:

    @interface MyBaseClass // << superclass omitted
    @property (nonatomic, readwrite, retain) NSObject *someObject;
    @end
    

    NSObject (or a subclass of, assuming you're target apple's systems) should be the base class unless you're very experienced and know what a root class is for.

    class extensions are often used to 'simulate' private interfaces. by simulate, the compiler doesn't enforce this, as it would be enforced in other languages. for example, all messages are still dynamic, although the subclass may (unknowingly) override methods in your extensions, if declared with the same selector.

    0 讨论(0)
  • 2020-12-04 17:11

    The solution you're after is to declare the MyBaseClass private property in a class extension:

    @interface MyBaseClass ()
    @property (nonatomic, readwrite, retain) NSObject *someObject;
    @end
    

    You are then free to make that declaration both in MyBaseClass and in MySubclass. This lets MySubclass know about these properties so that its code can talk about them.

    If the repetition bothers you, put the class extension in a .h file of its own and import it into both .m files.

    I will give an example from my own code. Here is MyDownloaderPrivateProperties.h:

    @interface MyDownloader ()
    @property (nonatomic, strong, readwrite) NSURLConnection* connection;
    @property (nonatomic, copy, readwrite) NSURLRequest* request;
    @property (nonatomic, strong, readwrite) NSMutableData* mutableReceivedData;
    @end
    

    There is no corresponding .m file and that's all that's in this file; it is, as it were, purely declarative. Now here's the start of MyDownloader.m:

    #import "MyDownloader.h"
    #import "MyDownloaderPrivateProperties.h"
    @implementation MyDownloader
    @synthesize connection=_connection;
    @synthesize request=_request;
    @synthesize mutableReceivedData=_mutableReceivedData;
    // ...
    

    And here's the start of its subclass MyImageDownloader.m:

    #import "MyImageDownloader.h"
    #import "MyDownloaderPrivateProperties.h"
    

    Problem solved. Privacy is preserved, as these are the only classes that import MyDownloaderPrivateProperties.h so they are the only classes that know about these properties as far as the compiler is concerned (and that's all that privacy is in Objective-C). The subclass can access the private properties whose accessors are synthesized by the superclass. I believe that's what you wanted to accomplish in the first place.

    0 讨论(0)
  • 2020-12-04 17:15

    super.someObject = nil;. Inheritance means MyBaseClass is your super class.

    0 讨论(0)
  • 2020-12-04 17:19

    This is an alternative that meets most of the objectives.

    In your header, define the interface

    @interface MyBaseClass : NSObject {
        NSObject *inheritableObject;
    }
    @property (readonly) NSObject *inheritableObject;
    

    Now you can edit the inheritableObject in MyBaseClass as well as in any Class that inherits from MyBaseClass. However, from the outside, it is readonly. Not private as in the case of @interface MyBaseClass(), but protected from uncontrolled changes.

    0 讨论(0)
  • 2020-12-04 17:20

    Judging by the () after your base class name, it looks like you are declaring a private interface extension within your class implementation, is this the case? If so the variable will only be accessible from within that class implementation.

    Does your MyBaseClass inherits from NSObject directly?

    If so, you need to declare the someObject property in your interface file, as in:

    @interface MyBaseClass : NSObject
    {
    }
    @property (nonatomic, retain) NSObject *someObject;
    

    And then synthesize it like you are already doing.

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