已聲明的屬性和存取方法
一個屬性,按通常的理解就是對象封裝的狀態(tài)里的一項。它要么是一個特性,比如名字或者顏色;要么是與另一個或多個其他對象的關聯(lián)。對象的類定義了一個接口,使用該對象的用戶可以獲。╣et)和設置(set)封裝屬性中的數值。而執(zhí)行這個功能的方法就叫做存取方法。
存取方法共有兩種,且都要符合一套命名規(guī)約!癎etter(取值器)”存取方法能夠返回某個屬性的值,它的方法名和該屬性同名!癝etter(賦值器)”存取方法能夠給某個屬性賦予新的值,它的命名規(guī)約是 set屬性名稱: 這樣的形式,屬性名稱的首字母大寫。在 Objective-C 框架中,只有嚴格按照規(guī)約對存取方法進行命名才能實現多種技術。
Objective-C 提供了已聲明的屬性,可以作為聲明的便利途徑,有時還能作為存取方法的實現。在之前的ios應用程序開發(fā)教程中,你曾經聲明了 userName 屬性:
@property (nonatomic, copy) NSString *userName;
已聲明的屬性使得 getter 和 setter 方法無需在類里顯式聲明。相反,你在聲明屬性時可以決定其具體行為方式,然后要求編譯器基于屬性聲明,生成(或說創(chuàng)建)實際可用的 getter 和 setter 方法。已聲明的屬性減少了大量不必要的代碼,節(jié)省開發(fā)者的時間,并且讓你的代碼更加清爽、減少出錯的可能。
在類接口文件中,要包含屬性聲明和方法聲明;镜穆暶饕褂 @property 編譯器指令,后面是屬性的類型和名稱。你還可以為屬性設定不同的選項,也就是說可以調整存取方法的具體行為方式,比如屬性是否為弱引用,或者是否為只讀屬性。這些選項寫在 @property 指令后邊的圓括號中。
下邊的幾行代碼展示了更多屬性聲明的例子:
@property BOOL flag; // 默認是只聲明類型和名稱
@property (copy) NSString *nameObject; // 在賦值過程中拷貝對象
@property (readonly) UIView *rootView; // 只聲明 getter 方法
在類的實現代碼中,你要使用 @synthesize 編譯器指令來要求編譯器根據聲明的情況,生成存取方法:
@synthesize flag;
@synthesize nameObject;
@synthesize rootView;
你也可以把 @synthesize 語句放到一行里面:
@synthesize flag, nameObject, rootView;
在 @synthesize 指令中,你還可以命令編譯器添加相應的實例變量到類定義中去。要增加一個實例變量,在屬性的名稱后面寫一個等號,然后寫你想要的實例變量名稱:
@synthesize nameObject=_nameObject;
塊對象
塊對象是封裝了一系列功能的一個對象,或者更通俗地講,它是一個代碼片段,能夠在任何時刻被執(zhí)行。它們本質上就是可移植的匿名的函數,可以作為其他方法的參數傳入,也可以作為其他方法或函數的返回值。塊對象本身有含類型的參數表,可能帶有不確定的或已聲明的返回值類型。你可以把一個塊對象賦值給某個變量,然后在你需要的時候像調用函數一樣調用它就行了。
脫字符(^)是塊的語法標記。還有按照我們熟悉的參數語法規(guī)約所定義的返回值以及塊對象的主體(也就是可以執(zhí)行的代碼)。下圖是如何把塊對象賦值給一個變量的語法講解:

接下來,按照調用函數的方式調用塊對象變量就可以了:
int result = myBlock(4); // 結果是 28
塊對象可以在局部作用域之內共享數據。塊對象的這個特性非常有用,假設你實現了一個方法,該方法定義了一個塊對象,那么這個塊對象就可以訪問該方法內的局部變量和參數(包括堆棧變量),也可以訪問函數和全局變量,甚至包括實例變量。這種訪問是只讀性質的,但如果變量聲明使用了 __block 修飾符,則它的值可以在塊對象中被改變。即使在方法或函數封裝的塊對象返回一個值并銷毀其作用域之后,只要對該塊對象的引用不消失,局部變量作為塊對象的一部分將一直存在。
和方法、函數的參數類似,塊對象可以被當作一個回調函數。當方法或函數被調用時,它們會執(zhí)行某些功能,并在合適的時機回調之前調用它們的代碼(通過塊對象),來請求附加信息,或者從中獲取程序特定的行為。塊對象讓調用者能夠在調用的時候提供回調代碼。塊對象不會將請求數據打包到一個“上下文”結構中,而是從方法或函數的相同作用域中捕獲數據。由于塊對象代碼無需在單獨的方法或函數中另外實現,所以你的實現代碼能夠變得更加簡潔,可讀性更強。
Objective-C 框架有許多帶有塊對象參數的方法。比如這段,在 UIKit 框架里聲明了如下類方法,它有兩個塊對象參數:
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;
這個方法可以讓你生成一個動畫效果。第一個塊對象參數用來選擇動畫效果;第二個塊對象參數指定動畫完成后要執(zhí)行的任務。下面的例子中,第一個塊對象將視圖動畫的結尾 alpha 值設為 0(讓它變成透明的)。第二個塊對象則把整個視圖移除。
[UIView animateWithDuration:0.2 animations:^{
view.alpha = 0.0;
} completion: ^(BOOL finished) {
if (finished == YES)
[view removeFromSuperview];
}];
|