iPhone開發系列文章(三)-Objective-C語言簡介

來源:互聯網
上載者:User

本人翻譯的Apple Dev Center的技術資料並稍作修改。

轉載請註明出處:http://blog.csdn.net/zhyzh2046/

學習Objective-C:初級讀本Objective-C是一種簡單的電腦語言,支援複雜南通的物件導向編程。Objective-C從標準的ANSI C語言擴充而來,並提供了定義類、方法和屬性的文法,還有其它結構來促進類的動態擴充。類的文法和設計把部分基於第一種物件導向的程式設計語言Smalltalk。如果你有使用物件導向語言的經驗,接下來的資訊會幫你學習到Objective-C基本的文法。許多傳統的物件導向概念,如封裝、繼承和多態,都會在Objective-C中出現。但是會存在一些重要的不同之處,不過這篇文章會講解這些不同,而且還可以查到更加詳細的資訊。如果你從來沒有使用過物件導向語言,在開始之前,至少需要基本理解相關的概念。對象和物件導向結構的使用是設計iPhone程式的基礎,而且理解它們是怎樣互動的是建立程式的必要條件。使用Objective-C進行物件導向編程中介紹了物件導向概念概述。要瞭解關於Objective-C更加詳細的資訊和文法,請查閱Objective-C程式設計。

Objective-C:C語言的超集

Objective-C是C語言的ANSI版本的超集,支援相同的基礎文法。與C語言相同,Objective-C也會定義標頭檔和源檔案,將公用的聲明和實現分離。Objective-C標頭檔使用的副檔名列在表1中。 

 

表1 Objective-C原始碼的副檔名
副檔名 代碼類型
.h 標頭檔。標頭檔中包含類、類型、函數和常量的聲明。
.m 源檔案。這是源檔案的一種典型擴充,可以包含C代碼和Objective-C代碼。
.mm 源檔案。這種源檔案除了可以包含C代碼和Objective-C代碼之外,還可以包含C++代碼。這種副檔名只能用於你實際引用了C++的類,或者引用了Objective-C的功能。

 

當需要在標頭檔包含標頭檔時,可以使用標準的#include先行編譯指令,但是Objective-C提供了更好的方法。#import指令和#include指令是一樣的,除了它能保證相同的檔案永遠不會被引用多次。Objective-C的樣本和文檔都建議使用#import,你自己的代碼也應該如此。

Strings

作為C的超集,Objective-C在指定字串時,具有和C一樣的約定。換句話說,單個字元使用單引號,字串會使用雙引號包圍。但是,大多數Objective-C架構經常不使用C樣式的字串。取而代之,大多數架構將字串封裝在一個NSString對象中。

NSString類是字串的對象載體,它具有希望的所有優點,包括為處理任意長度的字串內建的記憶體管理、支援Unicode、Printf風格的格式化優點等等。但由於一些字串經常使用,Objective-C提供了一個速記符號從常量建立NSString對象。使用這用速記,你所要做的僅僅是在一個正常的雙引號包含的字串之前加上一個@符號,如下樣本: 

NSString* myString = @"My String "; 
NSString* anotherString = [NSString stringWithFormat:@"%d %s", 1, @"String"]; 

// Create an Objective-C string from a C string 
//從C字串建立Objective-C字串 
NSString* fromCString = [NSString stringWithCString:"A C string" encoding:NSASCIIStringEncoding]; 

Classes 

正如大部分其它物件導向語言一樣,Objective-C中的類是一個基本的結構體,封裝了一些資料以及操作這些資料的動作。對象是類運行時的執行個體,包含類中聲明的成員變數和類方法的指標在記憶體中的拷貝。

Objective-C中建立一個類需要截然不同的兩個部分:介面和實現。介面部分包含類的聲明,還會定義成員變數和與類相關聯的方法。實現部分包含類方法的實際實現代碼。圖1顯示了聲明一個叫做MyClass的類的文法,它繼承了NSObject基類。類聲明會以@interface先行編譯指令開始,以@end指令結束。類名之後(有一個冒號分開)是父類的名稱。類的成員變數在大括弧包含的代碼中聲明({和})。在成員變數之後的代碼塊是類聲明的方法列表。每個成員變數和方法的聲明之後都要以分號結尾。 
圖1 類的聲明

圖2顯示了上例中MyClass的實現。像類的聲明一樣,類的實現由兩個先行編譯指令來指示-在這裡是@implementation和@end。這些指令定義了範圍資訊,告訴編譯器需要將附上的方法和相關的類聯絡起來。因此,方法的定義與介面中聲明的要匹配,除了代碼塊的包含。

圖2 類的實現

注意:儘管上述例子中,類的聲明部分只聲明了一些方法,類是可以在這裡聲明屬性的。關於屬性的更多資訊,請看“屬性”一節。

當使用變數儲存物件時,經常會使用指標類型。Objective-C中,強型別和弱類型變數都可以儲存對象。強型別指標的變數在聲明時必須包含類名。集合類經常使用弱類型指標,因為可能還不知道集合中對象的類型。如果你習慣於使用強型別的程式設計語言,你可能會認為弱類型變數的使用會產生問題,但是實際上,在使用Objective-C編程時,它會帶來極大的便利,同時會帶來更好的擴充性。

下面這個例子示範了MyClass類的強型別和弱類型變數的聲明:

MyClass* myObject1; // 強型別
id myObject2; //弱類型

Methods 
方法
 

  

Objective-C語言中的類可以聲明兩種方法:執行個體方法和類方法。執行個體方法的執行者必須是類的一個特定執行個體。換句話說,在調用執行個體方法之前,必須先建立一個類的執行個體,之後必須使用這個執行個體來調用實際的方法。相比之下,類方法不需要建立類的執行個體,後面會有詳細的解釋。

  

方法的聲明由方法類型標識符、傳回型別、一個或多個署名關鍵字和參數的名稱、類型資訊組成。圖3中聲明了一個insertObject:atIndex:的執行個體方法。方法聲明的前面加上了一個減法符號(-),這說明這個方法是一個執行個體方法。方法的實際名稱(insertObject:atIndex:)是所有署名關鍵字串聯起來的,包括冒號字元。冒號說明參數的存在。如果方法沒有參數,第一個(唯一的)署名關鍵之後可以忽略冒號。這個例子中,方法含有兩個參數。圖3 聲明方法的文法當調用一個方法時,要通過"messaging”來通知相應的對象。這個例子中的訊息就是方法名和這個方法所需的參數資訊。發送到對象的所有訊息是動態發送的,因此這有利於Objective-C的多態特徵。換句話說,如果子類定義了與父類同名的方法,子類會第一個收到訊息,然後可以選擇是否要將這個訊息轉交給它的父類。 

訊息都是放在方括弧([和])中。在方括弧中,收訊息的對象放在左邊,訊息(和任何訊息需要的參數)放在右邊。例如,發送insertObject:atIndex:訊息給myArray對象,使用的文法如下:

[myArray insertObject:anObj atIndex:0];為避免聲明大量局部變數來儲存臨時資料,Objective-C支援嵌套訊息。每一個嵌套訊息的傳回值都可以作為另一個訊息的參數或者是目標。例如,上例中的任何變數都可以被替換成能得到值的訊息。因此,如果有另外一個對象myAppObject,它的方法方法可以訪問數組對象,並且有另外一個數組對象,可以將上面的例子寫出如下樣子:

[[myAppObject getArray] insertObject:[myAppObject getObjectToInsert] atIndex:0];儘管前面的例子是向一個類的執行個體發送訊息,還可以向類本身發送訊息。當向類發送訊息時,調用的方法必須定義成類方法而不是執行個體方法。可以這樣認為:類方法同C++語言中類的靜態成員方法有些相似(但又不是完全相似)。類方法有代表性的用法有,作為Factory 方法來建立類的一個新執行個體,或者用來訪問與類相關的一些共用資訊。類方法的定義文法與執行個體方法是完全一樣的,只有一點不同。類方法使用加法符號(+),而不是減法符號作為方法的類型標識符。下面的例子示範了類方法的使用,這裡它作為類的Factory 方法。在這裡,arrayWithCapacity:方法是類NSMutableArray的類方法,他會申請並初始化一個新的類執行個體並返回它。

NSMutableArray*   myArray = nil;    // nil 本質上與NULL相同

//建立新的數組並賦值給myArray變數
myArray = [NSMutableArray arrayWithCapacity:0];

 

Properties 屬性屬性是一種便利符號,用來代替存取方法(accessor methods)。屬性並不是在類的聲明中建立一個新的成員變數。他們僅僅為定義用來訪問已經存在的變數的方法指定的捷徑。類可以使用屬性標記來公開成員變數,而不是使用getter和setter方法。類還可以使用屬性來公開“virtual”(虛)的成員變數—它是動態計算的一部分資料並且並不實際儲存在成員變數中。 

實際點說,屬性的使用減少了你的冗餘代碼量。應為大部分存取方法用相似的方式實現,使用屬性可以不必為每一個成員變數提供截然不同的getter和setter方法。相反,你可以使用屬性的聲明指定具體的動作,在編譯的時,會根據聲明合成實際的getter和setter方法。 

因為屬性的聲明會建立實際的方法,可以和方法的聲明一起定義在類的介面中。基本的定義使用@property先行編譯指令,後邊是屬性的類型資訊和名稱。可以使用定製選項配置屬性,它定義了存取方法有怎樣的行為。下面的例子顯示了一些簡單的型別宣告:

@property BOOL flag;
@property (copy) NSString* nameObject;  // 賦值過程中拷貝對象
@property (readonly) UIView* rootView;  // 僅建立getter方法 

屬性的另一個好處是在代碼中可以使用點文法來訪問他們,如下示範:

 myObject.flag = YES;
 CGRect   viewFrame = myObject.rootView.frame;
 

儘管上面的例子中的對象和屬性的名字很做作,但是他們示範了屬性的靈活性。點文法實際上屏蔽了相關一系列方法的調用。每個可讀屬性由同名的方法支援。每個可寫屬性由附加的方法set PropertyName:支援,在這裡屬性名稱的第一個字母大寫了。(這些方法是屬性的實際實現,同時也是可以在沒有成員變數支援的類中包含屬性定義的原因。)不用屬性去實現上面程式碼完成的功能,你需要編寫如下代碼:

 [myObject setFlag:YES];
 CGRect   viewFrame = [[myObject rootView] frame];
 

關於在類中如何聲明屬性的更多資訊,請查閱Objective-C程式設計中”屬性”一節。 

Protocols and Delegates 協議和代理

 

協議聲明的方法可以被任何一個類實現。協議不是類本身。他們僅定義了其它對象有責任實現的介面。當在自己的類中實現協議的方法時,你的類就是遵守這個協議的。 

iPhone OS中,協議經常被用作實現代理對象。代理對象是一個能代表其它對象或與其它對象合作的一個對象。學習協議、代理和其它對象相互影響的最好方法就是從例子中學習。 

UIApplication類實現了應用程式所需的功能。不是強制繼承UIApplication類來接收一個簡單的應用程式目前狀態的通知,而是UIApplication類調用賦值給代理對象的方法來分發這些通知。實現了UIApplicationDelegate協議方法的對象可以接收這些通知並提供合適的響應。 

協議的聲明類似於類介面的聲明,有一點不同的是,協議沒有父類,並且不能定義成員變數。下面的例子示範了只有一個方法的協議的聲明:

@protocol MyProtocol
- (void)myProtocolMethod;
@end

 

很多代理協議中,採用協議只是大概實現了協議中定義的方法。一些協議需要明確聲明支援的協議,但是現在假設僅實現方法就足夠了。但是,如果想將更多的只是應用到你的開發中,你應該多花些時間來學習協議和他們的使用方法,可以通過查閱Objective-C程式設計中的”協議”一節。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.