自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Cocoa學(xué)習(xí)筆記 設(shè)計模式詳解

移動開發(fā) iOS
本文介紹的Cocoa學(xué)習(xí)筆記 設(shè)計模式詳解,從多個方面介紹了Cocoa的設(shè)計模式,我們來看內(nèi)容。

Cocoa學(xué)習(xí)筆記 設(shè)計模式詳解是本文要介紹的內(nèi)容,文章中中讓我們從多個方面去了解和學(xué)習(xí)Cocoa的設(shè)計模式,不多說,我們來看內(nèi)容。

枚舉器 

類似于java容器類中的iterator,用以遍歷類中的元素

  1. NSDictionary *Mycollection;  
  2.     NSEnumerator *enumerator=[Mycollection objectEnumerator];  
  3.     while (instance=[enumerator nextObject]) {  
  4.         //  
  5.     } 

***的objective c引入了快速枚舉,如下所示:

  1. id instance;  
  2. NSDictionary *Mycollection;  
  3. NSEnumerator *enumerator=[Mycollection objectEnumerator];  
  4. for (instance in Mycollection) {  
  5.     //  

NSEnumerator類本身也支持快速枚舉,因此可以采用下面的方式反序枚舉容器中的數(shù)據(jù)

  1. id instance;  
  2. NSArray *Mycollection;  
  3. NSEnumerator *enumerator=[Mycollection objectEnumerator];  
  4. for (instance in [Mycollection reverseObjectEnumerator]) {  
  5.     //  

要創(chuàng)建自定義的枚舉器,那么就要繼承NSEnumerator類,重要是override nextObject方法

要實現(xiàn)快速枚舉就必須實現(xiàn)NSFastEnumeration協(xié)議,主要是實現(xiàn)以下方法

  1. - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; 

執(zhí)行選擇器和延遲執(zhí)行 

在cocoa中對象的方法調(diào)用是采用一種消息的方式來執(zhí)行的,因此就需要對象能夠執(zhí)行某個操作,發(fā)送什么消息才能讓對象啟動執(zhí)行某個操作,發(fā)送的消息的內(nèi)容

在cocoa中采用選擇器的方式確定發(fā)送給對象的消息,并且接收消息的對象使用選擇器來選擇調(diào)用哪個方法

  1. //聲明一個selector并初始化  
  2.  
  3.     SEL aSelector=@selector(application:didChangeStatusBarFrame:);  
  4.  
  5.     //聲明一個selector不初始化  
  6.  
  7.     SEL bSelector;  
  8.  
  9.     //向?qū)ο蟀l(fā)送selector  
  10.  
  11.     id result1=[Mycollection performSelector:aSelector];  
  12.  
  13.     id result2=[Mycollection performSelector:@selector(application:didChangeStatusBarFrame:)];  
  14.  
  15.     //檢測對象是否支持該方法  
  16.  
  17.     if ([Mycollection respondsToSelector:aSelector]) {  
  18.  
  19.         //OK  
  20.  
  21.     }  
  22.  
  23.     //動態(tài)創(chuàng)建類和selector  
  24.  
  25.     id class=[[NSClassFromString(@"TestTableAppDelegate") alloc] init];  
  26.  
  27.     [class performSelector:NSSelectorFromString([NSString stringWithFormat:@"setA%i",i])]; 

selector的基本原理就是apple的運(yùn)行庫通過在類自身內(nèi)緩沖每個選擇器的IMP來快速搜索對應(yīng)的函數(shù)指針,也可以自己找到對應(yīng)的指針

  1. [Mycollection methodForSelector:aSelector];  
  2. [NSDictionary instanceMethodForSelector:aSelector]; 

歸檔與解檔

說白了就是對象序列化

  1. NSData *data=[NSKeyedArchiver archivedDataWithRootObject:self.window];  
  2.   //用戶默認(rèn)數(shù)據(jù)存取  
  3.   //存到默認(rèn)數(shù)據(jù)中  
  4.   [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"窗口數(shù)據(jù)"]; 

通過類似的技術(shù)可以把符合協(xié)議的任何對象進(jìn)行歸檔,下面是協(xié)議的定義,***個用于歸檔的時候,第二個用于解檔的時候

  1. @protocol NSCoding  
  2.  
  3. - (void)encodeWithCoder:(NSCoder *)aCoder;  
  4. - (id)initWithCoder:(NSCoder *)aDecoder;  
  5. @end 

對象要支持歸檔與解檔就必須實現(xiàn)NSCoding協(xié)議

如果對象是繼承于父類,那么在實現(xiàn)NSCoding協(xié)議的時候還必須調(diào)用父類的對應(yīng)方法,如下所示

  1. @implementation TestClass  
  2. @synthesize test1=_test1;  
  3. static NSString *CodingKeyTest1=@"Test1";  
  4. - (void)encodeWithCoder:(NSCoder *)aCoder{  
  5.     [aCoder encodeObject:self.test1 forKey:CodingKeyTest1];  
  6. }  
  7.  
  8. - (id)initWithCoder:(NSCoder *)aDecoder{  
  9.     if (nil!=(self=[super initWithCoder:aDecoder])) {  
  10.         [self setTest1:[aDecoder decodeObjectForKey:CodingKeyTest1]];  
  11.     }  
  12.     return self;  
  13. }  
  14. @end 

cocoa單態(tài)模式舉例

書上的例子很多是錯誤的,不知道怎么搞的

  1. static TestClass *_shareInstance=nil;  
  2. - (void)encodeWithCoder:(NSCoder *)aCoder{  
  3.     _test2=@"test";  
  4.     self->_test2=@"test2";  
  5.     [aCoder encodeObject:self.test1 forKey:CodingKeyTest1];  
  6. }  
  7. - (id)initWithCoder:(NSCoder *)aDecoder{  
  8.     if (nil!=(self=[super initWithCoder:aDecoder])) {  
  9.         [self setTest1:[aDecoder decodeObjectForKey:CodingKeyTest1]];  
  10.     }  
  11.     return self;  
  12. }  
  13.  
  14. (id)hiddenAlloc{  
  15.     return [super alloc];  
  16. }  
  17. //單態(tài)模式,不允許創(chuàng)建對象  
  18. (id)alloc{  
  19.     return [[self shareInstance] retain];  
  20. }  
  21.  
  22. (id)new{  
  23.     return [self alloc];  
  24. }  
  25. (id)allocWithZone:(NSZone *)zone{  
  26.     return [[self shareInstance] retain];  
  27. }  
  28. - (id)copyWithZone:(NSZone *)zone{  
  29.     return [[self shareInstance] retain];  
  30. }  
  31.  
  32. - (id)mutableCopyWithZone:(NSZone *)zone{  
  33.     [self copyWithZone:zone];  
  34.     return self;  
  35. }  
  36. + (TestClass*)shareInstance{  
  37.     if (_shareInstance==nil) {  
  38.         _shareInstance=[[super allocWithZone:NULL] init];  
  39.     }  
  40.     return _shareInstance;  

通知

書上的例子很多是錯誤的,不知道怎么搞的

所謂通知也就是消息監(jiān)聽響應(yīng)模式,和MFC的實現(xiàn)有些類似,下面給個例子

要想對象能夠接收消息,那么就必須先把對象注冊到對象通知中心

  1. typedef  struct {  
  2.     int id;  
  3.     float  height;  
  4.     unsigned char  flag;  
  5. }MyTestStruct;  
  6. //將對象注冊到消息接收泵中  
  7.     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewDidChangeSelection:) name:
  8. @"NSTextViewDidChangeSelection" object:nil];  
  9. //對象接收到消息做出對應(yīng)處理的代碼  
  10. + (void)textViewDidChangeSelection:(NSNotification *)aNotification{  
  11.     NSValue *oldValue=[[aNotification userInfo] objectForKey:@"用鍵值查找數(shù)據(jù)"];  
  12.     MyTestStruct _teststruct;  
  13.     [oldValue getValue:&_teststruct];  
  14.     NSLog(@"%f打印結(jié)果咯",_teststruct.height);  
  15. }  
  16. //發(fā)送消息給對象  
  17.  
  18. - (void) postMessage{  
  19.     //發(fā)送通知  
  20.     MyTestStruct _teststruct;  
  21.     _teststruct.id=0;  
  22.     _teststruct.height=10.2;  
  23.     NSValue *_value=[NSValue valueWithBytes:&_teststruct objCType:@encode(MyTestStruct)];  
  24.     NSDictionary *_dic=[[NSDictionary alloc] initWithObjectsAndKeys:_value, @"用鍵值查找數(shù)據(jù)",nil];  
  25.     [[NSNotificationCenter defaultCenter] postNotificationName:@"NSTextViewDidChangeSelection" object:self userInfo:_dic];  

委托

說白了,就是另外一個對象的引用

比如A要給B發(fā)送消息,那么A中就保存一個B的實例引用,所以在cocoa的類中很多內(nèi)部都有個無類型的實例變量

  1. id delegate; 

再比如資源文件創(chuàng)建的窗口也有一個delegate,這個delegate要連接到某個類的delegate,那么這個類的委托就可以這樣聲明

  1. @property(nonatomic,readwrite,assign) IBOutlet id delegate; 

也可以定義成符合某種protocol的委托,如下:

  1. @property(nonatomic,readwrite,assign) IBOutlet id<UITableViewDelegate> delegate; 

插座 目標(biāo)  動作

插座變量主要用于連接Nib文件創(chuàng)建的實例,在從nib文件中加載并初始化了所有對象之后,將給加載的每個對象發(fā)送一條如下所示的消息

  1. - (void)awakeFromNib; 

對象接收到這個消息后就會把它的所有插座變量都設(shè)置為在Interface Builder中給它們提供的值

所謂目標(biāo)就是target,在cocoa中很多類都提供了一個名為target的插座變量和對應(yīng)名為action的實例變量

NSControl  NSActionCell  NSMenuItem實現(xiàn)了setTarget方法來設(shè)置目標(biāo)

任何返回void并且接受一個對象參數(shù)的方法都可以用作動作

用setAction方法來設(shè)置動作

不管發(fā)送動作消息是為了干什么,都是使用NSApplication類的-sendAction:to:from:方法來完成發(fā)送

NSApplication類是一個單態(tài)類,因此發(fā)送動作時一般使用如下

  1. [[UIApplication sharedApplication] sendAction: to: from: forEvent:]; 

響應(yīng)者鏈

在cocoa中所有響應(yīng)用戶輸入的對象都是抽象類NSResponder的子類

當(dāng)用戶處理應(yīng)用程序時,cocoa會自動跟蹤用戶的焦點位于何處,當(dāng)前正在接收鍵盤輸入的窗口稱為"關(guān)鍵"窗口,當(dāng)前具有焦點的文檔稱為“主”文檔,主文檔關(guān)聯(lián)的窗口稱為“主”窗口,在cocoa中應(yīng)用程序會自動追蹤關(guān)鍵窗口和主窗口,下面的方法分別獲得引用

  1. [[UIApplication sharedApplication] keyWindow];//iphone  
  2. [[NSApplication sharedApplication] mainWindow] ;//macos 

調(diào)用

大部分人都認(rèn)為selector與消息名稱是一回事,實際上不完全是,selector沒有提供任何類型信息,當(dāng)需要構(gòu)造一個消息的時候就需要知道每個參數(shù)的類型和返回值的類型,這種類型信息就稱為方法簽名(method signature)。

NSMethodSignature類封裝了這種信息,使用示例如下

  1. MyDocument *mydoc;  
  2. NSMethodSignature *mySig=[mydoc methodSignatureForSelector:@selector(window:shouldDragDocumentWithEvent:from:withPasteboard:)  ]; 

使用NSInvocation可以發(fā)送消息,創(chuàng)建它的實例,配置后可以多次使用,并獲得返回值 ,具體的實例就不寫了,參考下面的網(wǎng)址吧

http://www.cnblogs.com/chenjunbiao/archive/2011/04/20/2022197.html

享元

享元用來封裝非對象數(shù)據(jù),使得可以在上下文中使用,并且在需要大量實例時,享元減少了存儲需求

如 NSNumber  NSValue 

NSDate;

  1. NSDecimalNumber;  
  2. NSDate;  
  3. NSCalendarDate;  
  4. NSString;  
  5. NSURL;  
  6. NSFileHandle;  
  7. NSPipe;  
  8. NSAffineTransform;   

都是享元

NSColor ,NSFont;這些享元緩存并重用對象

[NSColor redColor];返回同一個共享實例,下一次請求還是用的同樣的一個實例

裝飾器 Decorator

就是對象之間的復(fù)合,減少類的數(shù)量, has-a

用于隱藏復(fù)雜性的模式

就是把資源雜七雜八的打包一起

獲得可執(zhí)行程序所在的包

  1. NSBundle *_budle=[NSBundle bundleForClass:[NSString class]]; 

動態(tài)加載可執(zhí)行代碼

  1. NSSearchPathForDirectoriesInDomains  //函數(shù)可以獲取所有的包路徑  
  2. _budle=[NSBundle bundleWithPath:@"路徑"];//動態(tài)加載包  
  3. BOOL isLoaded=[_budle load];//強(qiáng)制包的可執(zhí)行代碼鏈接進(jìn)應(yīng)用程序中  
  4. id class1=[_budle classNamed:@"類名"];//訪問包中的類 

類簇

Class Cluster模式給復(fù)雜的底層實現(xiàn)提供了一個簡單的接口

類簇的主要動機(jī)就是為了屏蔽內(nèi)部實現(xiàn)的復(fù)雜性,盡量提供簡單的接口

類簇模式利用的技術(shù)依賴于cocoa的兩階段創(chuàng)建模式,兩階段即內(nèi)存分配與初始化

利用兩階段創(chuàng)建,首先從+alloc 返回指向未初始化的新實例的存儲空間指針,然后利用-(id)init方法的某個遍體初始化新實例

因此通過init返回的可能就是公共接口的某個子類的實例,在init方法中首先要釋放掉已經(jīng)分配的抽象基礎(chǔ)類的實例,然后創(chuàng)建可以返回的想要的具體的子類的實例。

類簇的方式提供了簡單的接口,但是復(fù)雜化了子類的創(chuàng)建

管理者模式

顧名思義管理者就是管理其他類的實例的類,cocoa中的NSFileManager NSFontManager NSInputManager NSLayoutManager

在應(yīng)用程序設(shè)計中通常具有一個對象的集合,這些對象需要是唯一的,但是他們并不是單例

例如字體,字體可以有多種不同的字體,但是同一個字體在系統(tǒng)中有一個實例就夠了

小結(jié):Cocoa學(xué)習(xí)筆記 設(shè)計模式詳解的內(nèi)容介紹完了,希望本文對你有所幫助!

責(zé)任編輯:zhaolei 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-07-25 13:15:34

Cocoa MVC 架構(gòu)

2011-07-18 16:51:51

Cocoa 單態(tài) 模式

2011-07-26 10:42:00

Cocoa Cocoa2d 游戲

2011-07-26 17:31:52

iOS 設(shè)計模式

2011-07-07 16:14:37

Cocoa MVC 模型

2010-06-01 12:49:04

SVN分支模式

2011-08-15 16:09:44

Cocoa對象Objective-C

2011-08-10 18:47:18

Cocoa字符串

2011-07-08 18:03:30

Cocoa Touch 網(wǎng)絡(luò)

2021-06-29 08:54:23

設(shè)計模式代理模式遠(yuǎn)程代理

2011-07-22 15:50:06

Cocoa MVC 視圖

2011-07-08 16:09:54

Cocoa Cocos2d 動作

2011-08-02 13:58:18

Cocoa 框架 Mac OS

2011-08-15 14:47:28

Cocoa嵌入資源文件

2011-07-28 16:52:34

Cocoa 框架 Mac Os

2011-07-08 16:27:52

Cocoa Cocos2d 動作

2011-08-15 14:27:51

CocoaRunLoop

2009-08-18 11:03:31

Observer設(shè)計模

2012-07-10 02:01:53

設(shè)計模式命令模式

2010-07-15 18:04:20

Perl模式
點贊
收藏

51CTO技術(shù)棧公眾號