【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循环等待用户事件的时候,将一直保持运行而不会返回。
posted @ 2014-02-26 12:03  苹果吧  阅读(4501)  评论(0编辑  收藏  举报