加入RUN!PC粉絲團
最近新增的精選文章
 
最多人點閱的精選文章
 
 
精選文章 - 開發技術
分享到Plurk
分享到FaceBook
 
移動程式開發101(2-2)-環境與開發框架
文‧圖/何孟翰 2012/4/12 下午 03:47:34

Objective C語言
相較於Java的框架,你會發現Objective C或許較為陌生。然而你可以理解,要開發出好的iOS應用程式,對於Objective C的理解是非常必要的。或許你可以理解的是,Objective C是一個C語言的超級合,所以會依照C語言的方式和語法來解讀Objective C,然而或許你可以將它和Java或者是C++這些語言作比較。
Java語言之所以強大,是在當你學習了基礎的語法之後,你可以使用Java所提供的強大框架(Framework),也就是說例如像是Java的字串,工具程式,Collection框架等等在Java語言熟悉之後,不管是在J2SE的應用程式,J2EE的應用程式,甚至是Android的應用程式中都可以很自由的應用。
同樣的,Objective C絕對不止是物件導向的C語言這麼簡單,事實上它是基於Darwin,也就是以前Unix的一個分支的BSD上的一組應用程式的框架。而其中最重要的一個框架就是Foundaion框架和UIKit框架,也就是一組架在Cocoa Touch的框架。
Foundation框架
Foundation框架在iOS中提供了物件基礎的類別,你會發現這些類別都會有著NS的開頭。例如Foundation中的物件基礎類別就是NSObject。這個NS是NeXTSTEP的縮寫,也就是iOS和OSX的作業系統的前身。如果說一個物件和使用者介面沒有關聯,那它在iOS中就會是屬於Foundation框架的物件。

在Foundation框架下定義了這些物件與行為:
 定義物件的生成,協定,永續性與物件的記憶體管理,是不是可以在生成之後更改的這些特性,同時也會實作出物件彼此告知的這種機制。
 Foundation框架基於Unicode與字串,提供多語系的支援與語系的在地化。這個部份也讓iOS/OSX的應用程式能夠很輕鬆的支援多語系
 提供物件的基本資料型態,例如數值,字串和Collection框架,同時也提供了一些bsd的框架的延伸,例如執行緒,檔案系統與網路的port。

UIKit框架

在iOS框架推出時,有一個非常有魅力的名字叫作Cocoa Touch,如果Cocoa是一個Objective C在Mac OSX上的實作,你可以想像Cocoa Touch就是在Cocoa上加上了多點觸控的機制。而在iOS的這個Cocoa Touch框架上最重要的框架就是UIKit的框架。

事實上這個UIKit就是MacOSX下的AppKit同系列產品,它們都是在整個作業系統上,提供一組應用程式需要的類別,來生成並管理使用者介面。

一般來說,你在iOS中所看到的視覺元件,與它們的互動都是屬於UIKit的物件。我們可以使用下列三種方式來實作它。
1. 使用Interface Builder的方式來實作它。Interface Builder是一個XCode在舊一點版本的應用程式,現在已經被整合進XCode之中,但是簡單而言,就是你可以透過拖拉的方式,使用XCode的編輯器來設定物件並且使用它。
2. 直接在程式中生成這些UIKit的物件
3. 自定一個UIView的子類別,讓這個元件有自定的樣式與使用者互動的方法

因為UIKit的框架也是架在Cocoa Touch的基礎上,所以這組UIKit也是NSObject的子類別,同時你會看到它的名字都會用UI作開頭,例如UIScreen, UIApplication, UIViewController等等。

Objective C中的基本物件

經過前面的介紹,你可能會對Objective C中有一個簡單的理解,有點像是油水分離一樣,Objective C似乎有兩層,上層有一層Cocoa Touch的UIKit框架,而底層有一層很紮實的Foundation框架。換句話說,在Foundation框架的類別,可以和 Objective C沒有太直接的關聯。也就是說,NSObject的子類別,可以在非GUI的程式中使用。

事實上也是如此,如果你想要練習Foundation框架,同時還不想接觸太過複雜的UIKit(來避免干擾),你可以使用專案新增精靈,選擇Mac OSX底下的Application的類別,你可以看到一個Command Line的工具如圖3。



▲ 圖3 創建一個Command Line工具的專案



按下下一步之後,你可以看到一個專案設定的畫面,在底下的Type中可以看到C/C++/Core Data/Core Service和Foundation數種。如果你選擇C和C++,則這個專案就會使用一般的GNU C/C++,也就是gcc和g++的編譯器來完成專案的組態。而如果你使用Foundation時,就會使用到Objective C的Foundation函式庫如圖4。


▲ 圖 4 使用Objective C的Foundation框架


在這樣的專案中,你可以看到這個專案會連結Foundation的這個框架,同時也會幫你引入這些Foundation類別的函式庫宣告。特別是由於在Objective C中的物件都必須是NSObject的子類別,所以你可以發現在這個專案的.pch檔案,也就是前置編譯標頭檔(precompile header)中會引入
同時,Objective C是物件導向的,所以像是物件的繼承,封裝等等造成語言的可用性和多型等等都可以滿足。所以在Objective C中你也可以把物件想像成是一群的資料結構加上一些存取它的函數。

所以我們可以把Objective C的物件想像成是我們自訂的這些資料結構,加上NSObject的內容,也就是一個最重要的isa指標,它會指向這個物件所在的類別。而這個類別,如同一般的物件導向,就會將這些函數的表格與父類別函數的表格的參照建立起來,因此這個isa指標也是物件訊息遞送和物件動態化的主要機制。

也因此,Objective中表達物件可以有兩種方式,一種是用指標的型態來表示。假設有一個物件是Foo,則要表達它的實例,我們可以使用如下的方式:
Foo* aFooInstance;

也就是說,基於我們對C/C++的理解,你可以想像它是一個指標,指向Foo的這個類別的實例。然而,Objective C也允許另外一種動態的類型結構,也就是說我們可以使用如下的方式:
id anyInstance;
這是因為Objective C的執行環境允許在執行時期再檢視這個物件的類別與型態,進而可以知道要呼叫哪一個函數(類似多型),與動態模組的載入等等。
Objective C中超集合的介紹
因此,截至目前為止我們大概知道了Objective C中和物件導向語言一般容易理解的部份,例如類別與物件,繼承等等的概念。不過Objective C中還有多了一些不同的新功能

Categories
Categories可以允許你在既有的類別在不作子類別的情況下增加函數。當然這些增加的函數只能在你自己所寫的函數中使用。然而這些函數在執行時期,會和類別原先定義的函數一樣的被呼叫而沒有區別。所以它提供了一個簡便的方式讓我們對既有的類別增加功能。
Protocols
這裡的Protocols就像是Java裡的介面(interface),或者是C++中的抽象類別。在這些純定義不實作的函數列表中,可以讓物件導向語言輕易的達成多型效果。但是這個協定(protocol)在Objective中變得更有彈性,它有分正式(formal)和非正式(informal)兩種。
正式的協定在cocoa touch/iOS的實作上非常的常見,效用也和一般的Java的介面相同,都是定義了一個介面,有列出一系列的函數列表讓物件來實作。一般來說這種協定的運作如下:

1. 介面的提供者宣告了一個協定,並且列出要實作的函數列表
2. 客戶端會宣告依循這個協定,也因此要實作這些所需要實作的函數
3. 因此,如果有一個物件,它是由這個客戶端的類別而生成,由於它有實作所有的函數,所以它就有依循這個協定,也就可以被輕易的呼叫。

也因為協定是實作函數,所以一個類別可以依循超過一個協定,你可以使用如下的語法來實作ProtocolA, ProtocolB, ProtocolC三個協定:
@interface FOO : NSObject

在iOS常見的設計樣式中有一種叫作代理的設計樣式,也就是說有一些函數是在原本通用的類別中沒有定義或者需要客制化的,如果你需要實作一個類別來客制化這樣的通用類別,你只需要實作一個物件,並且依循它所定義的協定即可。

再談NSObject
因此,截至目前為止我們知道了ObjectiveC中的根類別是NSObject這個類別。然而,或許當你讀完了文件之後,你會發現NSObject也是一個協定。也就是說NSObject這個類別自身會依循NSObject這個協定。這個NSObject協定,定義了所有Cocoa中跟類別的基本程式設計介面。因此不止是NSObject,像是NSProxy,都會依循NSObject的協定。因此這些簡易的類別定義了以下的方式,幫助你作物件的生成與管理:
 alloc函數能幫你在記憶體中配置一個這個物件大小的非初始化函數,並且傳回一個物件的指標給你。此時你可以想像不同的類別alloc配置的空間都有所不同,所以這個函數是傳回一個id的指標。
 init函數能幫你作初始化的動作,通常和alloc一起使用。
 new函數能幫你作alloc和init是一個合併的簡易方法
 copy函數能夠複製該物件,有分可以更動的複製和不可以更動的複製兩種
同時更重要的,對於物件的生命周期,這個類別也定義了一些函數幫你管理
 retain可以增加物件的計數器並且取得物件擁有權
 release可以減少物件的計數器並且取消物件的擁有權
 autorelease可以在這個物件的scope結束時減少物件的計數器
 retainCount 可以取得物件目前的計數器參照
 dealloc 是由每一個類別自行實作的,會在物件被消滅時被呼叫,一般是用來消除實例變數,與動態配置的記憶體來減少記憶體洩露的情形

後記
在這一次的文章中我們說明了iOS和android的開發環境,同時也對Java的新版本和 Objective C的語言作了較具體的討論。在後續的文章中,我們會開始走訪這些程式設計的框架,讓你除了在開發這些移動式的App軟體之外,還能夠對這些程式語言所提供的框架,它們的設計樣式,甚至是一些實務的應用都能夠有更具體的了解。