1. 程式人生 > >Objective-C屬性詳解(附程式碼)

Objective-C屬性詳解(附程式碼)

宣告

在Objective-C中,有兩種宣告變數的方法,第一種直接宣告:

@interface Person : NSObject
{
    NSString *name;
    NSString *sex;
    NSString *age;
    Hand *hands[2];
    Foot *foots[2];

}

第二種可以使用屬性,關鍵字@property,顧名思義,屬性就是將變數看作是類的屬性:

@interface Person : NSObject
{

    NSString *name;
    NSString *sex;
    NSString
*age; Hand *hands[2]; Foot *foots[2]; } @property Foot* leftfoot; @property Foot* rightfoot; @property Hand* lefthand; @property Hand* righthand;

屬性與直接宣告變數不同的地方在於,如果直接宣告,在外面要想訪問name,需要設定他的setter,getter方法,不能直接訪問。
如果使用屬性的方法,可以這樣進行訪問

Person *person = [Person new];
person.leftfoot = [Foot new
]; [person setLeftfoot:[Foot new]]; Foot *foot1 = [person leftfoot]; Foot *foot2 = person.leftfoot;

如果實在類的內部可以像這樣訪問:

-(void)desc{
    [self.leftfoot desc];
    [_leftfoot desc];   
}

self.leftfoot與_leftfoot的訪問效果是一樣的。

屬性的引數

屬性的宣告是可以帶引數的,如下:

@property (nonatomic,strong) Foot* leftfoot;

nonatomic和strong都是屬性的引數,代表引數的一些特性:

atomic和nonatomic

atomic和nonatomic用來決定編譯器生成的getter和setter是否為原子操作。
設定成員變數的@property屬性時,預設為atomic,提供多執行緒安全。
nonatomic禁止多執行緒,變數保護,提高效能。

assign與retain

  1. 接觸過C,那麼假設你用malloc分配了一塊記憶體,並且把它的地址賦值給了指標a,後來你希望指標b也共享這塊記憶體,於是你又把a賦值給(assign)了b。此時a和b指向同一塊記憶體,請問當a不再需要這塊記憶體,能否直接釋放它?答案是否定的,因為a並不知道b是否還在使用這塊記憶體,如果a釋放了,那麼b在使用這塊記憶體的時候會引起程式crash掉。
  2. 瞭解到1中assign的問題,那麼如何解決?最簡單的一個方法就是使用引用計數(reference counting),還是上面的那個例子,我們給那塊記憶體設一個引用計數,當記憶體被分配並且賦值給a時,引用計數是1。當把a賦值給b時引用計數增加到2。這時如果a不再使用這塊記憶體,它只需要把引用計數減1,表明自己不再擁有這塊記憶體。b不再使用這塊記憶體時也把引用計數減1。當引用計數變為0的時候,代表該記憶體不再被任何指標所引用,系統可以把它直接釋放掉。總結:上面兩點其實就是assign和retain的區別,assign就是直接賦值,從而可能引起1中的問題,當資料為int, float等原生型別時,可以使用assign。retain就如2中所述,使用了引用計數,retain引起引用計數加1, release引起引用計數減1,當引用計數為0時,dealloc函式被呼叫,記憶體被回收。
@property (nonatomic,assign) Foot* leftfoot;
@property (nonatomic,retain) Foot* rightfoot;
person.leftfoot = [Foot new];
person.rightfoot = [Foot new];
Foot *foot1 = person.leftfoot;
Foot *foot2 = person.rightfoot;

這是對於leftfoot,編譯器就會爆出warning:

/Users/umeng/iosdev/Foundation/Foundation/main.m:17:25: Assigning retained object to unsafe property; object will be released after assignment

copy與retain

關於copy與retain,其實都會在賦值的時候,先釋放,但是一個是執行copy,一個是執行retain,這裡舉個例子,可能大家就明白了:

@property (nonatomic,copy) NSString* test;
@property (nonatomic,retain) NSString* test2;

然後進行賦值:

 NSMutableString *s = [[NSMutableString alloc]initWithString:@"hello"];
        Person *person = [Person new];
        person.test =s;
        person.test2 =s ;
        [s appendString:@" world"];
NSLog(@"%@:%@",person.test,person.test2);

結果:

Paste_Image.png

weak與strong

weak 和 strong 屬性只有在你開啟ARC時才會被要求使用,這時你是不能使用retain release autorelease 操作的,因為ARC會自動為你做好這些操作,但是你需要在物件屬性上使用weak 和strong,其中strong就相當於retain屬性,而weak相當於assign。

readwrite與readonly

readwrite 是可讀可寫特性;需要生成getter方法和setter方法時使用。
readonly 是隻讀特性 ,只會生成getter方法,不會生成setter方法 ;不希望屬性在類外改變。
對比程式碼效果更好一些,我將程式碼放在了github上:
https://github.com/mymdeep/OC_foundation
*更多的開發知識,可以關注我的公眾號: