How to declare instance variables and methods not visible or usable outside of the class instance?

前端 未结 3 1330
情书的邮戳
情书的邮戳 2020-12-13 10:58

I\'ve looked through a bunch of posts on this subject. Maybe I didn\'t run across \"the one\" and someone will point me in that direction. The question is simple and proba

相关标签:
3条回答
  • 2020-12-13 11:35

    You can declare instance variables or declared properties in a class extension. Since a class extension is declared in an implementation file (i.e., not a header file), they won’t be visible to someone inspecting the header file. For instance, in the header file:

    @interface SomeClass : NSObject
    @end
    

    and in the implementation file:

    @interface SomeClass ()
    @property (nonatomic, assign) int privateInt;
    @end
    
    @implementation SomeClass
    
    @synthesize privateInt;
    …
    @end
    

    or

    @interface SomeClass () {
        int privateInt;
    }
    @end
    
    @implementation SomeClass
    …
    @end
    

    Note that there’s nothing preventing access to private/class extension instance variables (or the accessor methods for properties declared in a class extension) during runtime. I’ve written a rather detailed post about this as an answer to another question on Stack Overflow: Does a private @property create an @private instance variable?

    Edit: Instance variables in class extensions were presented in WWDC 2010 session 144.

    Edit: "Using the Clang/LLVM 2.0 compiler, you can also declare properties and instance variables in a class extension."

    http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocCategories.html#//apple_ref/doc/uid/TP30001163-CH20-SW1

    0 讨论(0)
  • 2020-12-13 11:35

    You can use @private to specify that ivars are private. There is no way to make a method private, however. Even if the method is not listed in the header file, if someone knows the name and arguments they can call it.

    0 讨论(0)
  • 2020-12-13 11:39

    Use class extensions to add to a class in your implementation file. A class extension is basically an unnamed category with a few bonuses: properties declared in it can be synthesized and anything declared in it must be in the main implementation, so the compiler can check to make sure you didn't miss an implementation. You must put the class extension before your implementation. You can't add instance variables directly in a class extension, but you can add properties. When you synthesize accessors for properties which don't have corresponding instance variables, the new runtime (os x 10.5 and later and all versions of iOS, I believe) will create the instance variables automatically. This means you can't create your own accessors, however, unless you put the instance variable in your header. Private methods can be added to the class extension without restriction, but as Anomie noted, it is technically possible to use them if you know what they are called, and with class-dump, nothing is safe.

    Example usage of a class extension:

    @interface MyClass ()
    @property (retain) id privateIvar;
    @property (readwrite) id readonlyProperty; // bonus! class extensions can be used to make a property that is publicly readonly and privately readwrite
    - (void)privateMethod;
    @end
    @implementation MyClass
    @synthesize privateIvar; // the runtime will create the actual ivar, and we just access it through the property
    - (void)privateMethod {
        ...
    }
    ...
    

    Another way of creating "instance variables" without putting them in the header or using a property is to use associative references, which add data to an object at runtime. They aren't technically the same as instance variables, and the syntax for them is more complex. Since they also require the new runtime, there are only two reasons you would ever really want to use them: you want to add an instance variable in a category (outside the scope of this question) or you need it to be really really private. An associative reference doesn't create any methods or add to the class's definition in the compiled code, so if you don't create wrappers for them it is impossible to find out about them without asking the object after you add the data. See the bottom of the page I linked for a complete usage example.

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