第二章、Objective-c 語法,類/屬性/函式(iOS學習筆記,從零開始。)
注*需要具備面向物件程式設計基礎。
一、OC常識
- Objective-C是C的超集,也就是說C有的Objective-C都有,Objective-C多了C自身沒有的OO(面向物件)特性。
- Objective-C預設副檔名為 .m 。標頭檔案副檔名跟普通C一樣 .h 。
- Objective-C推薦引入標頭檔案的方式為:#import ,等同於C++的#include
二、從“類”說起
類是面向物件程式設計師賴以生存的工具。
在C++、Java和C# 中,定義一個類都使用關鍵字class,而在OC(Objective-c)中,定義一個類的關鍵字卻變成了@interface.如圖1
上圖(1)
1. 類定義在@interface和@end之間,類名MyClass 繼承自NSObject。
2.大括號{ }中定義類的屬性成員。
3.函式定義,其中“-/+”定義的是方法訪問許可權,-定義的是物件的方法,+定義的是類的方法,類似C++的靜態函式。
4.訪問許可權:Objective-C也像C++一樣有 public private protect 三種訪問許可權,預設的許可權是protected。
public 關鍵字修飾資源,可以在任何地方訪問。
protected 關鍵字修飾資源,可以在類內和其子類裡訪問。
private 關鍵字修飾資源,只能在類內訪問。
例如:iOS自帶的UITableView定義就又@private
UIKIT_CLASS_AVAILABLE(2_0)@interface UITableView :UIScrollView <NSCoding> {
@private
UITableViewStyle _style;
.....}
5.類的例項化:
MyClass *c = [[MyClass alloc] init];這裡【不能】像C++那樣:MyClass c;
來例項化一個Person的變數。另Objective-C都是使用指標來操作物件的。
三、再說屬性
屬性的定義 Object-C的物件可以使用強型別引用和弱型別引用,從上圖1中得知:
MyClass *myObject1; // Strong typing 強型別的定義方法,該定義方法與C++類似,容易理解
id myObject2; // Weak typing
其中 id myObject2是一種弱型別的定義方法,弱型別的物件主要用於集合類,集合類的物件通常在執行時才知道集合中內部的物件型別定義。弱型別的引用的使用與OC的動態型別繫結(Dynamic typing)息息相關,在OC中,每一個物件包含一個成員變數isa,儲存著物件屬於哪一個類的型別資訊。於是,開發人員能夠在執行時刻知道物件的定義,例如,其父類是什麼,實現了什麼函式等。
總結:id 這個型別讓人費解,通常id這個詞不太可能是資料型別。其實我把它理解成void* 或者uint型別,代表是一個指標的意思。在使用的時候強行轉換為具體的型別,這也是C++慣用的做法。
屬性宣告property的語法為:
@property (引數) 型別 名字;例如helloworld裡的AppDelegate類的標頭檔案如下:
#import <UIKit/UIKit.h>
@classViewController;
@interface AppDelegate :UIResponder <UIApplicationDelegate>
@property (strong,nonatomic)UIWindow *window;
@property (strong,nonatomic)ViewController *viewController;
@end
1,讀寫屬性(readwrite/readonly):顧名思義不用多說2,設定屬性(assign/retain/copy):assign為直接賦值,適合數值型別的;retain最常用,一般物件都用這個代表保留;copy為複製,多用於字串。
3,原子性atomicity(nonatomic):預設是atomic,如果是多執行緒的程式要保證某一個成員變數的一致性,須使用 atomic。
四、函式定義、呼叫
Object-C的函式定義和呼叫都比較怪異,為了讓物件執行某個操作,需要向物件傳送訊息,因此,函式的呼叫被稱作Object Messageing。其訊息的定義是[Receiver Message],前者是接收訊息的物件,後者是訊息的本身。此處先看看函式的定義:圖2
上圖(2)
函式的定義由函式的型別標記(Method type identifier)、返回值(return type)、一個或者多個的函式簽名關鍵字(Method signature)、引數的型別和命名資訊組成。
從上圖中我們很難看到函式的名字和引數是什麼!
那麼,函式的真實命名由各個級聯的函式簽名關鍵字組成。例如上述函式定義中函式真實的命名是:“insertObject:atIndex:”,
函式的形參就是anObject和
index兩個。
tips:當註冊回撥函式的時候,這個函式簽名關鍵字一定要帶上":"冒號,比如:
這裡的RegressionSlideCB原型是:- (void)RegressionSlideCB:(NSTimer*)theTimer把這個函式註冊到NSTimer裡。
原始程式碼如下:
iRegressionPer = [NSTimerscheduledTimerWithTimeInterval:0.1ftarget:self selector:@selector(RegressionSlideCB) userInfo:nilrepeats:ETrue];
NSTimer死活不回撥RegressionSlideCB,很是納悶兒。
注意:@selector(RegressionSlideCB)函式關鍵字後面沒有冒號,害的我查半天。加上冒號就是完整的函式名字了。
Objective-C的這種signature,看似是Objective-C獨有的,但是,讀過《深度探索C++物件模型》這本書的同學會發現,C++在處理基類和派生類的相同函式時,如何區分的問題。也用到signature的方法,即把“引數和函式名稱編在一起”。相信OC和C++都有相互借鑑。
函式呼叫,再來看一個例子:
//函式定義
- (int)changeColorToRed:(float)red green:(float)green blue:(float)blue;
//函式呼叫
[selfchangeColorToRed:5.0green:2.0blue:6.0];
上面第二行程式碼,如果用C++的思維會是 myColor->changeColorTo(5.0,2.0,6.0),現在看來雖然OC函式定義,乍看起來比較費解
,但是呼叫的時候更像是再閱讀一段文字。
總結:這就是OC的優雅之處吧,也開始慢慢喜歡OC的風格了,至少在寫程式碼時不用按住shift來輸入小括號了。哈哈!也許讓一個程式設計零基礎的新人,他會覺得OC的方式更容易理解。
以上部分內容摘自部落格: http://blog.csdn.net/shallon_luo/article/details/6217663,對博主的奉獻精神表示感謝。