天天看點

OC中變量的兩種聲明方式分析

在OC中聲明執行個體變量的方式有兩種:

{

    類型   執行個體變量名;

}

另外一種是用@property (屬性)類型  執行個體變量名;

下面來看一個簡單的OC程式:

@interface A : NSObject

@property  int x;

-(void) initVar;

@end

#import "A.h"

@implementation A

@synthesize x ;

-(void) initVar

{

    _x = 100;

    NSLog(@"%d ",_x);

}

@end

#import "A.h"

@interface B : A

-(void) printVar;

@end

@implementation B

-(void) printVar

{

   NSLog(@"x = %i",x);

}

@end

在上面這個簡單的繼承中是用第一種方法對執行個體變量進行聲明的,此時要想在A的子類B中通路A中所聲明的 x 變量就可以用執行個體變量名 x 直接通路,相當于用NSLog(@"x = %i ", self -> x); 如果用 @property (屬性) int x; @synthesize x; 對 x 進行聲明,則需要用到NSLog(@"x = %i ", self.x);在子類中對父類執行個體變量進行通路;這是什麼原因呢?解釋如下:

其中在類的繼承中對于第一種方式子類能夠直接通路到父類中得執行個體變量,此時可以用執行個體變量名直接通路,也相當于self ->執行個體變量,因為此時聲明的執行個體變量是protected類型的,在外部不能通路,但是可以在其子類中直接通路。

當用@property和 @synthesize 配合聲明執行個體變量時,不僅将執行個體變量聲明出來,同時也生成了執行個體變量的set 和 get方法,而且此時的執行個體變量為private類型的,這時在其子類中就不能通路到該類的執行個體變量,而是通過通路執行個體變量所對應的set、get方法來對執行個體變量進行通路,此時用 self.執行個體變量名進行通路。

在4.3版本以上的Xcode之後,在開發IOS程式的過程中,大家都習慣的将 @synthesize  執行個體變量名;省去不寫,隻通過@property進行聲明,然後再本類中通過在變量名前面加上下劃線 _ 如:(_x)進行對執行個體變量的通路;這時候的_x 隻是執行個體變量的屬性名,而在其子類中要通過調用對應的方法進行通路;

在這可以說明一下 點(.)操作還有 -> 操作:

其中前者對應的是通路方法;

而 -> 操作符則是直接對執行個體變量進行通路

還有一種解釋的方式:

可以将@property所聲明的執行個體變量作為是方法名而不是執行個體變量名,即對應相應的set 和get方法。(因為在系統所自帶的一些協定中,有一部分方法是通過@property 進行聲明的,然後協定的要求是隻能增加方法,但不能增加執行個體變量,可見這裡面所聲明的并不是執行個體變量,而是其所對應的方法)

是以在子類通路的過程中由@property聲明的要通過點(.)操作符調用執行個體變量的set、get函數進行對執行個體變量的通路;

而直接聲明的執行個體變量可以直接通過執行個體變量名進行通路;

備注:第二種解釋的方法有點牽強,希望大家可以綜合這兩種方式對着兩種聲明方式進行了解及運用。