Objective-C中的@property和@synthesize用法

@表明「Objective-C」的標誌,證實您正在使用Objective-C語言 php

Objective-C語言關鍵詞,@property與@synthesize配對使用。 html

功能:讓編譯好器自動編寫一個與數據成員同名的方法聲明來省去讀寫方法的聲明。 多線程

如: app

一、在頭文件中: 函數

C代碼
  1. @property int count; 

@property int count;

等效於在頭文件中聲明2個方法: 性能

C代碼
  1. - (int)count; 
  2. -(void)setCount:(int)newCount; 

- (int)count;
-(void)setCount:(int)newCount;

二、實現文件(.m)中 ui

C代碼
  1. @synthesize count; 

@synthesize count;

等效於在實現文件(.m)中實現2個方法。 編碼

C代碼
  1. - (int)count 
  2.     return count; 
  3. -(void)setCount:(int)newCount 
  4.     count = newCount; 

- (int)count
{
	return count;
}
-(void)setCount:(int)newCount
{
	count = newCount;
}

 

以上等效的函數部分由編譯器自動幫開發者填充完成,簡化了編碼輸入工做量。 atom

格式: spa

聲明property的語法爲:@property (參數1,參數2) 類型 名字;

如:

C代碼
  1. @property(nonatomic,retain) UIWindow *window; 

@property(nonatomic,retain) UIWindow *window;

其中參數主要分爲三類:

讀寫屬性: (readwrite/readonly)

setter語意:(assign/retain/copy)

原子性: (atomicity/nonatomic)

各參數意義以下:

readwrite: 產生setter\getter方法

readonly: 只產生簡單的getter,沒有setter。

assign: 默認類型,setter方法直接賦值,而不進行retain操做

retain: setter方法對參數進行release舊值,再retain新值。

copy: setter方法進行Copy操做,與retain同樣

nonatomic: 禁止多線程,變量保護,提升性能

參數類型

參數中比較複雜的是retain和copy,具體分析以下:

getter 分析

一、

C代碼
  1. @property(nonatomic,retain)test* thetest; 
  2. @property(nonatomic ,copy)test* thetest; 

@property(nonatomic,retain)test* thetest;
@property(nonatomic ,copy)test* thetest;

等效代碼:

C代碼
  1. -(void)thetest 
  2.   return thetest; 

-(void)thetest
{
  return thetest;
}

二、

C代碼
  1. @property(retain)test* thetest; 
  2. @property(copy)test* thetest; 

@property(retain)test* thetest;
@property(copy)test* thetest;

等效代碼:

C代碼
  1. -(void)thetest 
  2.     [thetest retain]; 
  3.     return [thetest autorelease]; 

-(void)thetest
{
	[thetest retain];
	return [thetest autorelease];
}

setter分析

一、

C代碼
  1. @property(nonatomic,retain)test* thetest; 
  2. @property(retain)test* thetest; 

@property(nonatomic,retain)test* thetest;
@property(retain)test* thetest;

等效於:

C代碼
  1. -(void)setThetest:(test *)newThetest { 
  2.     if (thetest!= newThetest) { 
  3.         [thetestrelease]; 
  4.         thetest= [newThetest retain]; 
  5.     } 

-(void)setThetest:(test *)newThetest {
	if (thetest!= newThetest) {
   		[thetestrelease];
  		thetest= [newThetest retain];
	}
}

 

二、

C代碼
  1. @property(nonatomic,copy)test* thetest; 
  2. @property(copy)test* thetest; 

@property(nonatomic,copy)test* thetest;
@property(copy)test* thetest;

等效於:

C代碼
  1. -(void)setThetest:(test *)newThetest { 
  2.     if (thetest!= newThetest) { 
  3.         [thetest release]; 
  4.         thetest= [newThetest copy]; 
  5.     } 

-(void)setThetest:(test *)newThetest {
	if (thetest!= newThetest) {
  		[thetest release];
  		thetest= [newThetest copy];
	}
}

nonatomic

若是使用多線程,有時會出現兩個線程互相等待對方致使鎖死的狀況(具體能夠搜下線程方面的注意事項去了解)。在沒有(nonatomic)的狀況下,即默認(atomic),會防止這種線程互斥出現,可是會消耗必定的資源。因此若是不是多線程的程序,打上(nonatomic)便可

retain

代碼說明

若是隻是@property NSString*str; 則經過@synthesize自動生成的setter代碼爲:

C代碼
  1. -(void)setStr:(NSString*)value{ 
  2.     str=value; 

-(void)setStr:(NSString*)value{
	str=value;
}

 

若是是@property(retain)NSString*str; 則自動的setter內容爲:

C代碼
  1. -(void)setStr:(NSString*)v{ 
  2.     if(v!=str){ 
  3.         [str release]; 
  4.         str=[v retain]; 
  5.     } 

-(void)setStr:(NSString*)v{
	if(v!=str){
		[str release];
		str=[v retain];
	}
}

全部者屬性

咱們先來看看與全部權有關係的屬性,關鍵字間的對應關係。

屬性值 關鍵字 全部權
strong __strong
weak __weak
unsafe_unretained __unsafe_unretained
copy __strong
assign __unsafe_unretained
retain __strong
strong

該屬性值對應 __strong 關鍵字,即該屬性所聲明的變量將成爲對象的持有者。

weak

該屬性對應 __weak 關鍵字,與 __weak 定義的變量一致,該屬性所聲明的變量將沒有對象的全部權,而且當對象被破棄以後,對象將被自動賦值nil。

而且,delegate 和 Outlet 應該用 weak 屬性來聲明。同時,如上一回介紹的 iOS 5 以前的版本是沒有 __weak 關鍵字的,因此 weak 屬性是不能使用的。這種狀況咱們使用 unsafe_unretained。

unsafe_unretained

等效於__unsafe_unretaind關鍵字聲明的變量;像上面說明的,iOS 5以前的系統用該屬性代替 weak 來使用。

copy

與 strong 的區別是聲明變量是拷貝對象的持有者。

assign

通常Scalar Varible用該屬性聲明,好比,int, BOOL。

retain

該屬性與 strong 一致;只是可讀性更強一些。

參考:

http://blog.eddie.com.tw/2010/12/08/property-and-synthesize/

http://www.cocoachina.com/bbs/read.php?tid=7322

http://www.cnblogs.com/pinping/archive/2011/08/03/2126150.html

聲明的分類

Objective-C官方文檔 中的Property一章裏有對類Property詳細說明。
@property中的聲明列表已分類爲如下幾種:

1, 聲明屬性的訪問方法:

  • getter=getterName
  • setter=setterName
    聲明訪問屬性的設置與獲取方法名。

2,聲明屬性寫操做權限:

  • readwrite
    聲明此屬性爲讀寫屬性,便可以訪問設置方法(setter),也能夠訪問獲取方法(getter),與readonly互斥。
  • readonly
    聲明此屬性爲只讀屬性,只能訪問此屬性對應的獲取方法(getter),與readwrite互斥。

3,聲明寫方法的實現:

  • assign
    聲明在setter方法中,採用直接賦值來實現設值操做。如:
C代碼
  1. -(void)setName:(NSString*)_name{ 
  2.      name = _name; 

-(void)setName:(NSString*)_name{
     name = _name;
}

  • retain
    聲明在setter方法中,須要對設過來的值進行retain 加1操做。如:
C代碼
  1. -(void)setName:(NSString*)_name{ 
  2.      //首先判斷是否與舊對象一致,若是不一致進行賦值。 
  3.      //由於若是是一個對象的話,進行if內的代碼會形成一個極端的狀況:當此name的retain爲1時,使這次的set操做讓實例name提早釋放,而達不到賦值目的。 
  4.      if ( name != _name){ 
  5.           [name release]; 
  6.           name = [_name retain]; 
  7.      } 

-(void)setName:(NSString*)_name{
     //首先判斷是否與舊對象一致,若是不一致進行賦值。
     //由於若是是一個對象的話,進行if內的代碼會形成一個極端的狀況:當此name的retain爲1時,使這次的set操做讓實例name提早釋放,而達不到賦值目的。
     if ( name != _name){
          [name release];
          name = [_name retain];
     }
}

  • copy
    調用此實例的copy方法,設置克隆後的對象。實現參考retain。

4,訪問方法的原子性:

  • nonatomic
    在默認的狀況下,經過synthesized 實現的 setter與getter 都是原子性訪問的。多線程同時訪問時,保障訪問方法同時只被訪問一個線程訪問,如:
  • C代碼
    1. [ _internal lock ]; // lock using an object-level lock 
    2. id result = [ [ value retain ] autorelease ]; 
    3. [ _internal unlock ]; 
    4. return result; 

    [ _internal lock ]; // lock using an object-level lock
    id result = [ [ value retain ] autorelease ];
    [ _internal unlock ];
    return result;

  • 但若是設置nonatomic時,屬性的訪問爲非原子性訪問。

來源:http://wiki.magiche.net/pages/viewpage.action?pageId=1540101

@synthesize tabBarController=_tabBarController;

@synthesize 中能夠定義 與變量名不相同的getter和setter的命名,籍此來保護變量不會被不恰當的訪問

相關文章
相關標籤/搜索