【IOS學習】之四、協議,委托,分類粗解


何為協議,何為委托,何為分類(類別)?

委托  即 代理 delegate:

 

 他是 (接口的實現類)類似c中的回調。
        把某個對象要做的事情委托給別的對象去做。 那么別的對象就是這個對象的代理,來代替他處理要做的事情。
在code中,首先你要明確一個對象的委托方是誰,委托的內容是什么。
         在mfc中,每個程序都要繼承自cwinapp,就是要重寫幾個虛函數額。
         但是在cocoa中,我們來實現個UIApplicationDelegate代理,不用繼承,我們只需要考慮你要捕獲的應用程序生命周期中的函數就可以了。
         可以這樣用指針來看: 類a中有一個類b的指針,那么b就是a的代理委托。a干完一件事情就需要告訴b,b調用對應的方法來做出相應的響應。
         ios開發中: 如:視圖之間傳輸信息。  兩個頁面uiview   來實現傳值,用delegate可以很好地做到。
 
來看一個demo:  
  1. @interface A: UIView  
  2.   
  3. @property(nonatic, retainid aValueDelegate;  
  4.   
  5. @end;  
  6.   
  7. @implementation A  
  8.   
  9. - (void) fa  
  10. {  
  11.      NSString *value = @"hello";  
  12.      [aValueDelegate aValue:value];  
  13. }  
  14.   
  15. @end;  
  16.   
  17. @interface B: UIView  
  18. NSString *value;  
  19. @end;  
  20.   
  21. @implementation B  
  22.   
  23. - (void) aValue:(NSString *)fromValue  
  24. {  
  25.      value = fromValue;  
  26.      NSLog(@"%@", value);  
  27. }  
  28.   
  29. @end;  
  30.   
  31. A *a = [[A alloc] init];  
  32. B *b = [[B alloc] init];  
  33. a.aValueDelegate = b;   //設置a代理委托對象為b  
類別:category  主要3個功能
1、利用類別分散實現。
2、利用類別創建前向引用,實現私有函數
3、非正式協議和委托類別  
  1. @interface NSString(NumberConvenience)  
  2. -(NSNumber*) lengthAsNumber;  
  3. @end  

協議:   類似於c++的純虛函數(java中的接口),  只有聲明,沒有實現,  你需要在子類中實現。
其中@optional 屬性方法不要求必須實現。   
      @required屬性 要求實現協議的類必須要實現方法。
 
如果不確定協議是否被實現,可以使用respondsToSelector:@select()來判斷。
協議不是類,就是簡單定義了一個其他對象可以實現的接口。
 
demo是采用源哥博客(http://blog.csdn.net/xie376450483/article/details/7646617)的代碼:
代碼根據xcode的升級,有些許改動。
非正式協議:        是使用類別category來實現,他是nsobject的一個類別。這樣任何類的對象都可以作為委托對象來使用。他可以列出對象能夠執行的多種方法。這樣用來實現委托我們可以使用選擇器來判斷非正式協議中是否有這個方法。  
  1. @interface NSObject (***Delegate)  
  2. //method  
  3. @end  
 
  1. //  
  2. //  Dog.h  
  3. //  protocol2  
  4. //  
  5. //  Created by peter on 14-2-25.  
  6. //  Copyright (c) 2014年 peter. All rights reserved.  
  7. //  
  8.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. @interface Dog : NSObject  
  12.   
  13. @property int ID;  
  14.   
  15. @end  
  16.   
  17. @interface NSObject(myCategory)  
  18.   
  19. - (void)callFromNSObject;  
  20.   
  21. @end  
  22.   
  23. //  
  24. //  Dog.m  
  25. //  protocol2  
  26. //  
  27. //  Created by peter on 14-2-25.  
  28. //  Copyright (c) 2014年 peter. All rights reserved.  
  29. //  
  30.   
  31. #import "Dog.h"  
  32.   
  33. @implementation Dog  
  34.   
  35. - (id)init  
  36. {  
  37.     self = [super init];  
  38.     return self;  
  39. }  
  40.   
  41. @end  
  42.   
  43.   
  44. @implementation NSObject(myCategory)  
  45.   
  46. - (void)callFromNSObject  
  47. {  
  48.     NSLog(@"iam nsobject");  
  49. }  
  50.   
  51. @end  
  52.   
  53. //  
  54. //  Person.h  
  55. //  protocol2  
  56. //  
  57. //  Created by peter on 14-2-25.  
  58. //  Copyright (c) 2014年 peter. All rights reserved.  
  59. //  
  60.   
  61. #import <Foundation/Foundation.h>  
  62. #import "Dog.h"  
  63.   
  64.   
  65. @interface Person : NSObject  
  66. //{  
  67. //    Dog *dog;  
  68. //}  
  69.   
  70. @property Dog *dog;  
  71.   
  72. - (void)callFun;  
  73.   
  74. @end  
  75.   
  76. //  
  77. //  Person.m  
  78. //  protocol2  
  79. //  
  80. //  Created by peter on 14-2-25.  
  81. //  Copyright (c) 2014年 peter. All rights reserved.  
  82. //  
  83.   
  84. #import "Person.h"  
  85.   
  86. @implementation Person  
  87.   
  88. @synthesize dog;  
  89.   
  90. - (void) callFun  
  91. {  
  92.     NSLog(@"Call Fun!");  
  93.     [dog callFromNSObject];  
  94. }  
  95.   
  96. @end  
  97.   
  98. //  
  99. //  main.m  
  100. //  protocol2  
  101. //  
  102. //  Created by peter on 14-2-25.  
  103. //  Copyright (c) 2014年 peter. All rights reserved.  
  104. //  
  105.   
  106. #import <Foundation/Foundation.h>  
  107. #import "Dog.h"  
  108. #import "Person.h"  
  109.   
  110. int main(int argc, const charchar * argv[])  
  111. {  
  112.   
  113.     @autoreleasepool {  
  114.         Dog *dog = [[Dog alloc]init];  
  115.         [dog setID:10];  
  116.         Person *qy = [[Person alloc]init];  
  117.         [qy setDog:dog];  
  118.         [qy callFun];  
  119.     }  
  120.     return 0;  
  121. }  

正式協議: 一個命名方法列表。  與非正式的區別在於:他要求顯示采用協議,采用協議的方法是在類的@interface聲明中列出協議的名稱。  這時實現協議的類應該遵守協議,承諾實現協議中的所有方法。  
  1. @protocol NSCopying  
  2. -(id) copyWithZone:(NSZone *) zone;  
  3. @end  
  4.   
  5. @interface Car : NSObject<NSCopying>  
  6. {  
  7. // instance variable  
  8. }  
  9. // method  
  10. @end // Car  

cocoa china中的總結:
  1.協議聲明了可以被任何類實現的方法
  2.協議不是類,它是定義了一個其他對象可以實現的接口
  3.如果在某個類中實現了 協議 中的某個方法,也就是這個類實現了那個 協議
  4.協議經常用來實現委托對象。一個委托對象是一種用來協同或者代表其他對象的特殊對象。
  5:委托,就是調用自己定義方法,別的類來實現。
  6.新特性說明
    @optional預編譯指令:表示可以選擇實現的方法
    @required預編譯指令:表示必須強制實現的方法  
  1. @protocol myprotocol <NSObject>  
  2. @optional  
  3. -(void)print:(int)value;  
  4. //可選的方法  
  5.   
  6. @required  
  7. -(int)printValue:(int)value1 andValue:(int)value2;  
  8. //必須實現的  
  9.   
  10. @end  
  11.   
  12. #import <Foundation/Foundation.h>  
  13. #import "myprotocol.h"  
  14. //實現協議 myprotocol  
  15. @interface mytest : NSObject<myprotocol>   
  16. - (void)showInfo;  
  17. @end  
  18.   
  19.   
  20. #import "mytest.h"  
  21.   
  22. @implementation mytest  
  23. -(void)showInfo  
  24. {  
  25.      NSLog(@"I am in showInfo");  
  26. }  
  27.   
  28. //實現協議必須實現的  
  29. -(int)printValue:(int)value1 andValue:(int)value2  
  30. {  
  31.      NSLog(@"print value1 %d,value2 %d",value1,value2);  
  32.      return 0;  
  33. }  
  34.   
  35. //實現可選的  
  36. -(void)print:(int)value  
  37. {  
  38.      NSLog(@"print value is %d",value);  
  39. }  
  40.   
  41. @end  
  42.   
  43. #import <Foundation/Foundation.h>  
  44. #import "mytest.h"  
  45. #import "myprotocol.h"  
  46.   
  47. int main (int argc, const charchar * argv[]) {  
  48.    @autoreleasepool {  
  49.           mytest *test=[[mytest alloc]init];  
  50.           [test showInfo];  
  51.           [test printValue:20 andValue:30];  
  52.           //print協議是可選的,所以在用之前一定要判斷是否實現了,不然可能會出錯,使用下面的方法  
  53.      //     [test print:20];  
  54.           SEL sel=@selector(print:);  
  55.           if([test respondsToSelector:sel]){  
  56.                [test print:11];  
  57.           }  
  58.        
  59.           //用協議的方式實現  
  60.           id<myprotocol> protocol =[[[mytest alloc]init]autorelease];  
  61.           [protocol showInfo];  
  62.           [protocol printValue:200 andValue:300];  
  63.           if([protocol respondsToSelector:@selector(print:)]){  
  64.                [protocol print:111];  
  65.           }  
  66.    }  
  67.     return 0;  
  68. }  


最后看一個demo,加深理解:  
  1. //  
  2. //  Dog.h  
  3. //  catagory  
  4. //  
  5. //  Created by peter on 14-2-25.  
  6. //  Copyright (c) 2014年 peter. All rights reserved.  
  7. //  
  8.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. @protocol dogBark;  
  12.   
  13. @interface Dog : NSObject  
  14. {  
  15.     int barkCount;  
  16.     NSTimer *timer;  
  17. }  
  18.   
  19. @property int ID;  
  20. @property (assign)id<dogBark> delegate;     //dog master  
  21.   
  22. @end  
  23.   
  24. @protocol dogBark <NSObject>  
  25.   
  26. - (void)bark: (Dog*)thisDog count:(int)count;  
  27.   
  28. @end  
  29.   
  30. //  
  31. //  Dog.m  
  32. //  catagory  
  33. //  
  34. //  Created by peter on 14-2-25.  
  35. //  Copyright (c) 2014年 peter. All rights reserved.  
  36. //  
  37.   
  38. #import "Dog.h"  
  39.   
  40. @implementation Dog  
  41.   
  42. //ID use _ID  
  43. @synthesize delegate;  
  44.   
  45. - (id)init  
  46. {  
  47.     if (self = [super init]) {  
  48.         //create nstimer user, 1.0s use updateTimer:nil  
  49.         timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];  
  50.          
  51.     }  
  52.     return self;  
  53. }  
  54.   
  55. - (void) updateTimer:(id)arg  
  56. {  
  57.     barkCount++;  
  58.     NSLog(@"dog bar %d", barkCount);  
  59.      
  60.     //user master delegate  bark:count  
  61.     [delegate bark:self count:barkCount];  
  62. }  
  63.   
  64. @end  
  65.   
  66. //  
  67. //  person.h  
  68. //  catagory  
  69. //  
  70. //  Created by peter on 14-2-25.  
  71. //  Copyright (c) 2014年 peter. All rights reserved.  
  72. //  
  73.   
  74. #import <Foundation/Foundation.h>  
  75. #import "Dog.h"  
  76.   
  77. @interface person : NSObject<dogBark>  
  78. {  
  79.     Dog *_dog;  
  80. }  
  81.   
  82. @property (retainnonatomicDog *dog;  
  83.   
  84. @end  
  85.   
  86. //  
  87. //  person.m  
  88. //  catagory  
  89. //  
  90. //  Created by peter on 14-2-25.  
  91. //  Copyright (c) 2014年 peter. All rights reserved.  
  92. //  
  93.   
  94. #import "person.h"  
  95.   
  96. @implementation person  
  97.   
  98. - (void)setDog:(Dog *)aDog  
  99. {  
  100.     if (_dog != aDog) {  
  101.         [_dog setDelegate:self];  
  102.     }  
  103. }  
  104.   
  105. //dog use person interface  
  106. - (void)bark:(Dog *)thisDog count:(int)count  
  107. {  
  108.     NSLog(@"person bark: this dog %d bark %d", [thisDog ID], count);  
  109. }  
  110.   
  111. @end  
  112.   
  113. //  
  114. //  main.m  
  115. //  catagory  
  116. //  
  117. //  Created by peter on 14-2-25.  
  118. //  Copyright (c) 2014年 peter. All rights reserved.  
  119. //  
  120.   
  121. #import <Foundation/Foundation.h>  
  122. #import "Dog.h"  
  123. #import "person.h"  
  124.   
  125. int main(int argc, const charchar * argv[])  
  126. {  
  127.   
  128.     @autoreleasepool {  
  129.         person *qy = [[person alloc]init];  
  130.         Dog *dog = [[Dog alloc]init];  
  131.         [dog setID:10];  
  132.         [qy setDog:dog];  
  133.          
  134.         while (1) {  
  135.             [[NSRunLoop currentRunLoop]run];  
  136.         }  
  137.     }  
  138.     return 0;  
  139. }  

解釋一下循環:
 [[ NSRunLoop  currentRunLoop ] run ];  run是一種cocoa構造,一直處於阻塞狀態, 知道某些事情發生未知。
run循環等待用戶事件的時候,將一直保持運行而不會返回。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM