2011-12-14 64 views
11

在Objective-c 2.0中,爲什麼子類需要使用self關鍵字引用父類中的實例變量?繼承Objective-c中的實例變量

考慮這個例子:

// a.h 
@interface MyClass : NSObject 
@property (nonatomic, retain) Object *myObject; 
@end 

// a.m 
@implementation MyClass 
@synthesize myObject; 
@end 


// b.h 
@interface AnotherClass : MyClass 
@end 

// b.m 
@implementation AnotherClass 
- (void) someMethod { 
    // error 
    // Object *obj = myObject; 

    // works 
    // Object *obj = self.myObject; 
} 
@end 
+2

這是[Kevin Ballard的回答](http://stackoverflow.com/a/8511046/)解釋爲[合成ivars的可見性是多少?](http://stackoverflow.com/questions/8510464/) )從幾個小時前。 – 2011-12-14 21:46:43

回答

11

您還沒有真正定義的變量,你只定義一個財產(其隱含地定義一個變量,它是私有的)。由於屬性只是方法,你需要點語法。請注意0​​與[self property]相同。

要解決這個問題,請指定一個變量。我會給你一個例子,其中變量的名稱不同於屬性。大多數人都爲這兩個人選擇了相同的名字,但我喜歡讓他們有所不同,所以我立即明白哪一個的意思。

// a.h 
@interface MyClass : NSObject { 
    // Instance variables are "protected" by default, except if you 
    // use @private or @public. 
    Object *myObjectVar; 
} 

@property (nonatomic, retain) Object *myObject; 
@end 

// a.m 
@implementation MyClass 
@synthesize myObject = myObjectVar; 
@end 


// b.h 
@interface AnotherClass : MyClass 
@end 

// b.m 
@implementation AnotherClass 
- (void) someMethod { 
    // works 
    Object *obj = myObjectVar; 

    // works 
    obj = self.myObject; 

    // the same as self.myObject 
    obj = [self myObject]; 
} 
@end 

注意,當你分配的區別:如果您分配給變量的對象不會自動保留。

myObjectVar = someObject; // not retained, old object not released! 
self.myObject = someObject; // old object released, new object retained 
[self setMyObject:someObject]; // same as the line above 

編輯:提到合成實例變量默認都是私有的,由@Jason可可注意但如果你使用屬性保留。而@NSGod是正確的,默認的實例變量是保護默認,而不是公開,固定的。

+1

`@綜合'屬性實際上確實創建了他們的名字的伊娃,但他們綜合了一個@私人的伊娃。你回答的工作是因爲你已經專門創建了伊娃,並將合成器分配給了一個限制較少的訪問級別,這並不是因爲合成器不生成Ivars。 – 2011-12-14 21:50:58

8

只要你真的在超類中聲明瞭一個實例變量,而不是依賴新運行時合成實例變量的能力(除了合成訪問器方法),它們不會。有關實例變量合成的更多信息,請參見The Objective-C Programming Language: Runtime Difference

例如,爲了能夠直接引用實例變量,你需要進行以下更改:

@interface MyClass : NSObject 
@property (nonatomic, retain) Object *myObject; 
@end 

到:

​​

默認情況下,實例變量@protected ,這意味着類和任何子類都可以直接訪問實例變量。 @protected ivars與@public ivars不同,因爲您無法使用->訪問它們。 @private ivars只能由聲明它們的類訪問。有關更多信息,請參見The Objective-C Programming Language: The Scope of Instance Variables