Objective C: Why do we declare ivars in the .h member area if @property seems to do it automatically?

前端 未结 4 873
一向
一向 2020-12-16 14:55

In implementing an interface it seems the common method in tutorials and literature is to declare an ivar and then set the @property then @synthesize

相关标签:
4条回答
  • It used to be necessary. There are two different versions of the Objective-C runtime: a 32-bit-only "legacy" runtime (the old one) and a 32/64-bit runtime (the new 32-bit runtime is only used on iOS devices and for the iOS simulator).

    I think the only place this is still necessary is when you're running the app in 32-bit mode (either 10.5 or 10.6). Everywhere else (64-bit Leopard, 64-bit Snow Leopard, Lion, iOS) uses the newer runtime that has "automatic ivar synthesis", and the resulting ivars are referred to as "synthesized ivars".

    0 讨论(0)
  • 2020-12-16 15:35

    Some platforms support synthesized instance variables, some don't. Explicitly declaring instance variables makes your code valid in more places, and it used to be outright necessary until very recently, so people still do it. In a few years, they probably won't anymore.

    0 讨论(0)
  • 2020-12-16 15:36

    The @property only implements the accessor methods, the instance variable itself has to exist. Try ignoring the ivars and it will fail on runtime, if not on compile time.

    0 讨论(0)
  • 2020-12-16 15:38

    Using modern versions of Xcode (anything about 4.2 or later) there is no reason to declare a iVar in your header, EVER. Anything publicly accessible should be declared as a property.

    Many forget that Objective C objects are actually pointers to C structs. As such, any iVar that is declared in your header can be accessed directly, by passing your getters and setters, using myObject->myPublicIVar. Especially in non-ARC code, that is extremely dangerous. The @private directive prevents the use the -> operator to access iVars, but still clutters the header file. There's no point in @private when there are better ways.

    Anything private should be declared within your .m file. Often, this requires a class extension, like this:

    // The .h file
    @interface Foo : NSObject
    @property (nonatomic, strong) NSString *myPublicString;
    @end
    
    
    // The .m file
    @interface Foo ()
    @property (nonatomic, strong) NSString *myPrivateString;
    @end
    
    @implementation Foo {
        NSString *myPrivateIVar;
    }
    
    // Xcode 4.5 or later will not require these @synthesize
    @synthesize myPublicString = _myPublicString;
    @synthesize myPrivateString = _myPrivateString;
    
    @end
    

    An implementation like this provides a public property backed by an iVar, a private property backed by an iVar, and a private independent iVar. I've included the @synthesize directives, but they are not necessary using modern tools.

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