zoukankan      html  css  js  c++  java
  • 【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循环等待用户事件的时候,将一直保持运行而不会返回。
  • 相关阅读:
    Java Native Method
    SQL语句优化
    Ibatis的环境搭建以及遇到的问题解决
    Java 构建器
    SpringMVC自定义视图 Excel视图和PDF视图
    java 枚举的常见使用方法
    mysql 根据某些字段之和排序
    MFC The Screen Flickers When The Image Zoomed
    How To Debug Qmake Pro File
    Gcc And MakeFile Level1
  • 原文地址:https://www.cnblogs.com/ios8/p/ios-delegate.html
Copyright © 2011-2022 走看看