Is this a new way to define private instance variables in Objective-C?

前端 未结 2 1730
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-09 00:08

I\'ve recently updated to Xcode 4.3.2 and found that I can now declare private instance variables inside @implementation block like so:

@interfa         


        
相关标签:
2条回答
  • 2020-12-09 00:43

    It's for real, it's the new way,* it's great, and, yes, it's in the docs. The Objective-C Programming Language, which is as close as we get to having an actual spec for the language, has the following to say:

    The definition of a class is structured very much like its declaration. It begins with an @implementation directive and ends with the @end directive. In addition, the class may declare instance variables in braces after the @implementation directive:

    @implementation ClassName
    {
        // Instance variable declarations.
    }
    // Method definitions.
    @end
    

    There's also a historical note a little ways back from that link, addressing the fact that we used to have to declare ivars in the interface block:

    Historically, the interface required declarations of a class’s instance variables, the data structures that are part of each instance of the class. ... Instance variables represent an implementation detail, and should typically not be accessed outside of the class itself. Moreover, you can declare them in the implementation block or synthesize them using declared properties. Typically you should not, therefore, declare instance variables in the public interface and so you should omit the braces.

    For the question of privacy, yes, these variables are truly private -- they act like ivars declared in the interface with the @private directive. This means that subclasses can't access them, by default. Their visibility can be changed, however, using either @protected or (if necessary for some bizarre reason) @public:

    @interface Stuper : NSObject 
    @end
    
    @implementation Stuper
    {
        @protected
        NSString * sangfroid;
    }
    @end
    
    @interface Stub : Stuper
    - (void)setSangfroid: (NSString *)newSangfroid;
    @end
    
    @implementation Stub
    
    - (void)setSangfroid: (NSString *)newSangfroid {
        sangfroid = [newSangfroid copy];
    }
    

    *You have to use clang > 3.0, I believe, so that's just a few months ago as of this posting. GCC won't do it.

    0 讨论(0)
  • 2020-12-09 00:43

    It's pretty new and it's valid as long as any compiler you need supports it.

    It's great for minimizing your dependencies -- the includes and forwards may largely be in the implementation file. For this reason, and if all the compilers you use support it, then it's a better place for your ivars than in the @interface block.

    A final caveat is that our current (may.2.2012) debuggers do not support this.

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