<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 22, comments - 32, trackbacks - 0, articles - 73
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    想從JAVA轉到obj-c,看了些基礎的東西,感覺很奇怪,可能不太習慣,在網上看到一個不錯文章有助理解obj-c的一些核心機制。

    Objective-C——消息、Category和Protocol

    2012-06-22 20:13 by 池建強, 2627 閱讀, 11 評論, 收藏, 編輯

    面向對象永遠是個可以吐槽的話題,從開始提出到推崇備至,到充滿質疑,一路走來讓人唏噓不已。面向對象的思想可謂歷史悠久,20世紀70年代的Smalltalk可以說是面向對象語言的經典,直到今天我們依然將這門語言視為面向對象語言的基礎。
    面向對象是大部分編程語言的基本特性,像 C++、Java、Objective-C這樣的靜態語言,Ruby、Python這樣的動態語言都是面向對象的語言。但是如何編寫面向對象的程序卻一直是困擾人們的話題,即使是Smalltalk,也有人認為這是一個有缺陷的面向對象的語言實現。
     
    我在2010年翻譯過的一篇InfoQ的文章,《面向對象編程──走錯了路》中提到,面向對象編程的三個原則是:基于消息傳遞機制,對象分離和多態。文章中還舉了Erlang例子,認為Erlang具備了這些原則,“所以可能是唯一的面向對象語言”。除了之前提到的三個特征,單繼承和動態類型也被引用為面向對象語言的“絕對需求”?;谶@些考慮,文章指出,Smalltalk在實現對象思想時的“錯誤”──例如,只關注狀態和行為,在類和基于映像的語言里缺乏良好的并發模型和消息機制。
     
    這篇文章中的核心就是,面向對象思想中除了對象的狀態、行為,還應該關注其并發機制、消息機制,后者更為重要。這一點事實上是我在接觸了Objective-C之后才有了更深入的體會。
     
    Ojbective-C的語法設計主要基于Smalltalk,除了提供傳統的面向對象編程特性之外,還增加了很多類似動態語言Ruby、Python才具有的特性,例如動態類型、動態加載、動態綁定等等,同時強化了消息傳遞機制和表意(Intention Revealing Interface)接口的概念。
     
    —消息—
    消息傳遞模型(Message Passing)是Objective-C語言的核心機制。在Objective-C中,沒有方法調用這種說法,只有消息傳遞。在C++或Java中調用某個類的方法,在Objective-C中是給該類發送一個消息。在C++或Java里,類與類的行為方法之間的關系非常緊密,一個方法必定屬于一個類,且于編譯時就已經綁定在一起,所以你不可能調用一個類里沒有的方法。而在Objective-C中就比較簡單了,類和消息之間是松耦合的,方法調用只是向某個類發送一個消息,該類可以在運行時再確定怎么處理接受到的消息。也就是說,一個類不保證一定會響應接收到的消息,如果收到了一個無法處理的消息,那么程序就是簡單報一個錯。甚至你可以向一個值為nil的空對象發送消息,系統都不會出錯或宕掉。這種設計本身也比較符合軟件的隱喻。
     
    在表意接口(Intention Revealing Interface)方面,Objective-C也是設計的比較出色的語言。面向對象語言的特性之一就是通過API把實現封裝起來,為上層建筑提供服務。但是需要注意的一點就是,你封裝的API最好能夠讓調用者看到接口描述就知道怎么使用。如果為了使用一個API必須要去研究它的實現,那么就失去了封裝的意義。Objective-C通過顯式的API描述,讓開發者不自覺的寫出滿足表意接口的API,比如下圖中的API描述。

     
    上圖中描述了一個傳統意義的實例方法,但和Java或C++不同的是,其方法關鍵字由多個字符串組成,在這個例子是insertObject和atIndex,(id)anObject和 (NSUInterger)index分別表示參數類型和參數名稱。整個方法看上去就像一個英語句子,我們可以很容易的知道,這個方法就是在索引為 index處插入一個對象。如果你是從其他語言轉到Objective-C,那么開始的時候會感覺這種寫法有些繁復,但是一旦理解并習慣了你會感受到其巨大的好處,這種寫法會強制你寫出優美易讀的代碼和API,而且有了XCode強大的提示功能,再長的方法也是一蹴而就。
     
    下面我們來說說多態和繼承。
     與Java一樣,Objective-C一樣不支持多重繼承,但是通過類別(Category)和協議(Protocol)可以很好的實現代碼復用和擴展。
     
    —Category—
    首先我們來談談Category。
     
    Objective-C提供了一種與眾不同的方式——Catagory,可以動態的為已經存在的類添加新的行為。這樣可以保證類的原始設計規模較小,功能增加時再逐步擴展。使用Category 對類進行擴展時,不需要訪問其源代碼,也不需要創建子類。Category使用簡單的方式,實現了類的相關方法的模塊化,把不同的類方法分配到不同的分類文件中。
     
    實現起來很簡單,我們舉例說明。
    SomeClass.h
    @interface SomeClass : NSObject{
    }
    -(void) print;
    @end 
     
    這是類SomeClass的聲明文件,其中包含一個實例方法print。如果我們想在不修改原始類、不增加子類的情況下,為該類增加一個hello的方法,只需要簡單的定義兩個文件 SomeClass+Hello.h和SomeClass+Hello.m,在聲明文件和實現文件中用“()”把Category的名稱括起來即可。聲明文件代碼如下:
     
    #import "SomeClass.h"
     
    @interface SomeClass (Hello)
    -(void)hello;
    @end
    實現文件代碼如下
    #import "SomeClass+Hello.h"
    @implementationSomeClass (Hello)
    -(void)hello{
        NSLog (@"name:%@ ", @"Jacky");
    }
    @end 
    其中Hello是Category的名稱,如果你用XCode創建Category,那么需要填寫的內容包括名稱和要擴展的類的名稱。這里還有一個約定成俗的習慣,將聲明文件和實現文件名稱統一采用“原類名+Category”的方式命名。
    調用也非常簡單,毫無壓力,如下:
    首先引入Category的聲明文件,然后正常調用即可。
    #import "SomeClass+Hello.h"
     
    SomeClass * sc =[[SomeClass alloc] init];
    [sc hello] 
    執行結果是:
    nameJacky 
     
    Category的使用場景:
    1、當你在定義類的時候,在某些情況下(例如需求變更),你可能想要為其中的某個或幾個類中添加方法。
    2、一個類中包含了許多不同的方法需要實現,而這些方法需要不同團隊的成員實現
    3、當你在使用基礎類庫中的類時,你可能希望這些類實現一些你需要的方法。
     
    遇到以上這些需求,Category可以幫助你解決問題。當然,使用Category也有些問題需要注意,
    1、Category可以訪問原始類的實例變量,但不能添加變量,如果想添加變量,可以考慮通過繼承創建子類。
    2、Category可以重載原始類的方法,但不推薦這么做,這么做的后果是你再也不能訪問原來的方法。如果確實要重載,正確的選擇是創建子類。
    3、和普通接口有所區別的是,在分類的實現文件中可以不必實現所有聲明的方法,只要你不去調用它。
     
    用好Category可以充分利用Objective-C的動態特性,編寫出靈活簡潔的代碼。
     
    —Protocol— 
    下面我們再來看Protocol。
    Protocol,簡單來說就是一系列不屬于任何類的方法列表,其中聲明的方法可以被任何類實現。這種模式一般稱為代理(delegation)模式。你通過Protocol定義各種行為,在不同的場景采用不同的實現方式。在iOS和OS X開發中,Apple采用了大量的代理模式來實現MVC中View和Controller的解耦。
     
    定義Protocol很簡單,在聲明文件(h文件)中通過關鍵字@protocol定義,然后給出Protocol的名稱,方法列表,然后用@end表示Protocol結束。在@end指令結束之前定義的方法,都屬于這個Protocol。例如:
    @protocol ProcessDataDelegate <NSObject>
    @required
    - (void) processSuccessful: (BOOL)success;
    
    @optional
    - (id) submitOrder: (NSNumber *) orderid;
    @end
     
    以上代碼可以單獨放在一個h文件中,也可以寫在相關類的h文件中,可以視具體情況而定。該Protocol包含兩個方法,processSuccessful和submitOrder。這里還有兩個關鍵字,@required和@optional,表示如果要實現這個協議,那么processSuccessful方法是必須要實現的,submitOrder則是可選的,這兩個注解關鍵字是在Objective-C 2.0之后加入的語法特性。如果不注明,那么方法默認是@required的,必須實現。
     
    那么如何實現這個Protocol呢,很簡單,創建一個普通的Objective-C類,取名為TestAppDelegate,這時會生成一個h文件和m文件。在h文件中引入包含Protocol的h文件,之后聲明采用這個Protocol即可,如下:
    @interface TestAppDelegate : NSObject<ProcessDataDelegate>;
    
    @end
    用尖括號(<...>)括起來的ProcessDataDelegate就是我們創建的Protocol。如果要采用多個Protocol,可以在尖括號內引入多個Protocol 名稱,并用逗號隔開即可。例如<ProcessDataDelegate,xxxDelegate>
     
    m文件如下:
    @implementation TestAppDelegate
    
    - (void) processSuccessful: (BOOL)success{
        if (success) {
            NSLog(@"成功");
        }else {
            NSLog(@"失敗");
        }
    }
    
    @end 
    由于submitOrder方法是可選的,所以我們可以只實現processSuccessful。
     
    Protocol一般使用在哪些場景呢?Objective-C里的Protocol和Java語言中的接口很類似,如果一些類之間沒有繼承關系,但是又具備某些相同的行為,則可以使用 Protocol來描述它們的關系。不同的類,可以遵守同一個Protocol,在不同的場景下注入不同的實例,實現不同的功能。其中最常用的就是委托代理模式,Cocoa框架中大量采用了這種模式實現數據和UI的分離。例如UIView產生的所有事件,都是通過委托的方式交給Controller完成。根據約定,框架中后綴為Delegate的都是Protocol,例如UIApplicationDelegate,UIWebViewDelegate 等,使用時大家可以留意一下,體會其用法。
     
    使用Protocol時還需要注意的是:
    1、Protocol本身是可以繼承的,比如:
    @protocol A
         -(void)methodA;
    @end
    @protocol B <A>
         -(void)methodB;
    @end

    如果你要實現B,那么methodA和methodB都需要實現。 

    2、Protocol是類無關的,任何類都可以實現定義好的Protocol。如果我們想知道某個類是否實現了某個Protocol,還可以使用conformsToProtocol進行判斷,如下:
    [obj conformsToProtocol:@protocol(ProcessDataDelegate)] 
     
    好吧,具體的語言特性這次就介紹這么多。從某種意義上來說,Objective-C是一門古老的語言,發明于1980年。1988年,喬布斯的Next公司獲得了Objective-C語言的授權,并開發出了Objective-C的語言庫和NEXTSTEP的開發環境。NextStep是以Mach和BSD為基礎,Objective-C是其語言和運行庫,后來的事大家都清楚,蘋果買了Next,喬布斯回歸蘋果,開始神奇的蘋果振興之路,NextStep成了Max OS X的基礎。以后發展越來越好,Objctive-C成了Apple的當家語言,現在基本上是Apple在維護Objctive-C的發展。
     
    在蘋果的AppStore推出之前,Objective-C一直相對小眾,但是其優秀的語言特性似乎一直在為后面的爆發積蓄力量,當蘋果平臺級的應用出現之后,Objective-C開始大放異彩,靜態語言的效率和動態語言的特性得到眾多程序員的喜愛,目前它已經以火箭般的速度躥升TIOBE語言排行版第四位。
     
    對于喜愛蘋果技術的技術人員來說,Objective-C是你必須深入了解和值得學習的一門語言,希望以后有機會多寫一些相關的文章。

    轉載于:http://www.cnblogs.com/chijianqiang/archive/2012/06/22/objc-category-protocol.html

     


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 狠狠躁狠狠爱免费视频无码| 亚洲精品亚洲人成在线| 中文字幕免费视频精品一| 免费在线观看毛片| 污视频网站在线观看免费| 四虎永久免费观看| 色吊丝免费观看网站| 亚洲国产V高清在线观看| 一级一级毛片免费播放| 77777亚洲午夜久久多人| 最近免费字幕中文大全| 亚洲欧洲国产精品你懂的| 最近中文字幕免费mv在线视频| 亚洲精品在线免费看| 97在线线免费观看视频在线观看| 亚洲欧洲日韩国产一区二区三区| 全免费a级毛片免费看不卡| 国产成人亚洲精品播放器下载| 免费乱理伦在线播放| 本免费AV无码专区一区| 亚洲韩国—中文字幕| 免费不卡视频一卡二卡| 国产产在线精品亚洲AAVV| 红杏亚洲影院一区二区三区| 香蕉成人免费看片视频app下载| 亚洲精品日韩专区silk| 日韩一品在线播放视频一品免费| 无人视频免费观看免费视频| 亚洲成A人片在线观看无码不卡| 国产精品99久久免费观看| 最新亚洲卡一卡二卡三新区| 亚洲福利在线播放| 免费A级毛片无码视频| 亚洲国产系列一区二区三区| 亚洲人成网站18禁止一区| 99精品视频在线观看免费专区 | 久久精品亚洲中文字幕无码网站| 亚洲免费闲人蜜桃| 午夜在线免费视频| 亚洲蜜芽在线精品一区| 少妇亚洲免费精品|