首页 > 代码库 > 黑马程序员——OC语言的Block与Protocol(协议)

黑马程序员——OC语言的Block与Protocol(协议)

Block

● Block封装了一段代码,可以在任何时候执?行
● Block可以作为函数参数或者函数的返回值,?而其本?身又可以带输?入参数或返回值。

● 苹果官?方建议尽量多?用block。在多线程、异步任 务、集合遍历、集合排序、动画转场?用的很多

定义BLOCK变量

Int (^SumBlock)(int,int);//有参数,返回值类型为int

Void (^MyBlock)();//无参数,返回值类型为空

 

Blocks的定义:
int (^MySum)(int, int) = ^(int a, int b) { 

return a+b;

 };

定义了?一个叫MySum的blocks对象,它带有两个int参数,返回int。等式右边就 是blocks的具体实现

Block可以访问局部变量,但是不能修改。 int sum = 10;
int (^MyBlock)(int) = ^(int num) {

sum++;//编译报错

return num * sum;

 };

如果要修改就要加关键字:__block __block int sum = 10;

 
Blocks和函数指针对?比 ● 定义函数指针

int (*myFn)(); ● 定义Blocks

int (^MyBlocks)(int,int); ● 调?用函数指针

(*myFn)(10, 20);

● 调?用Blocks MyBlocks(10, 20);

Blocks的赋值
● 在声明的同时定义变量,然后赋值

int (^MySum)(int,int) = ^(int a,int b) {   return a + b;

};

● 也可先?用typedef先声明类型,再定义变量进?行赋值 typedef int (^MySum)(int,int);
MySum sum = ^(int a,int b) {

   return a + b;};

  1 //  2 //  main.m  3 //  04-block  4 //  5 //  Created by apple on 13-8-11.  6 //  Copyright (c) 2013年 itcast. All rights reserved.  7 //  8   9 #import <Foundation/Foundation.h> 10  11 /* 12  block要掌握的东西 13  1> 如何定义block变量 14  int (^sumBlock)(int, int); 15  void (^myBlock)(); 16   17  2> 如何利用block封装代码 18  ^(int a, int b) { 19     return a - b; 20  }; 21   22  ^() { 23     NSLog(@""); 28  }; 29   30  3> block访问外面变量 31  * block内部可以访问外面的变量 32  * 默认情况下,block内部不能修改外面的局部变量 33  * 给局部变量加上__block关键字,这个局部变量就可以在block内部修改 34   35  4> 利用typedef定义block类型 36  typedef int (^MyBlock)(int, int); 37  // 以后就可以利用MyBlock这种类型来定义block变量 38  MyBlock block; 39  MyBlock b1, b2; 40   41  b1 = ^(int a, int b) { 42     return a - b; 43  }; 44   45  MyBlock b3 = ^(int a, int b) { 46     return a - b; 47  }; 48  */ 49  50 typedef int (*SumP)(int, int); 51  52  53 typedef int (^MyBlock)(int, int); 54  55 int sum(int a, int b) 56 { 57     return a + b; 58 } 59  60 int main() 61 { 62     // int (*p)(int, int) = sum; 63     // int (*p2)(int, int) = sum; 64     // SumP p = sum; 65     // SumP p2 = sum; 66      67      68     /* 69     int (^sumBlock)(int, int); 70      71     sumBlock = ^(int a, int b) { 72         return a + b; 73     }; 74      75     int (^minusBlock)(int, int) = ^(int a, int b) { 76         return a - b; 77     };*/ 78      79     MyBlock sumBlock; 80     sumBlock = ^(int a, int b) { 81         return a + b; 82     }; 83      84     MyBlock minusBlock = ^(int a, int b) { 85         return a - b; 86     }; 87      88      89     MyBlock multiplyBlock = ^(int a, int b) { 90         return a * b; 91     }; 92      93      94     NSLog(@"%d - %d - %d", multiplyBlock(2, 4),  sumBlock(10 , 9), minusBlock(10, 8)); 95       96     return 0; 97 } 98  99 void test3()100 {101     int a = 10;102     __block int b = 20;103     104     void (^block)();105     106     block = ^{107         // block内部可以访问外面的变量108         //NSLog(@"a = %d", a);109         110         // 默认情况下,block内部不能修改外面的局部变量111         // a = 20;112         113         // 给局部变量加上__block关键字,这个局部变量就可以在block内部修改114         b = 25;115     };116     117     118     block();119 }120 121 // 有返回值、有形参的block122 void test2()123 {124     /*125      // 指针函数的指针126      int (*p)(int, int) = sum;127      int d = p(10, 12);128      NSLog(@"%d", d);129      */130     131     132     int (^sumblock)(int, int) = ^(int a, int b){133         return a + b;134     };135     136     int c = sumblock(10, 11);137     138     139     // 用一个block输出n条横线140     141     142     void (^lineBlock)(int) =  ^(int n)143     {144         for (int i = 0; i<n; i++) {145             NSLog(@"");169         NSLog(@"");175         NSLog(@"----------------");176     };177     178     // 利用block变量调用block内部的代码179     myblock();180     181     myblock();182 }

Protocol(协议)

1、 简单使用
1. 基本用途
可以用来声明一大堆方法(不能声明成员变量),不能写实现
只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法声明
只要父类遵守了某个协议,就相当于子类也遵守了

?Protocol声明的方法可以让任何类去实现,protocol就是协议。

?OC不能继承多个类(单继承)但是能够遵守多个协议。继承(:),遵守协议(< >)

?基协议:<NSObject>是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。

?协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明。

 

2. 格式
协议的编写

@protocol 协议名称

// 方法声明列表

@end

某个类遵守协议

@interface 类名 : 父类 <协议名称>

@end

 

3. 关键字

协议中有2个关键字可以控制方法是否要实现(默认是@required在大多数情况下,用途在于程序员之间的交流

@required:这个方法必须要实现(若不实现,编译器会发出警告)
@optional:这个方法不一定要实现

 

4. 协议遵守协议
一个协议可以遵守其他多个协议,多个协议之间用逗号 , 隔开
一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明

@protocol 协议名称 <协议1, 协议2>

@end

 

5. 基协议
NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它
其实还有一个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议
NSObject协议中声明很多最基本的方法,比如descriptionretainrelease
建议每个新的协议都要遵守NSObject协议

 

6. 定义变量时指定协议

// NSObject类型的对象,并且要遵守NSCopying协议

NSObject<NSCopying> *obj;

// 任何OC对象,并且要遵守NSCoding协议

id<NSCoding> obj2;

 

2、 代理设计模式
1. 设计原理
有些麻烦的事情不想自己亲自做,就可以找个人帮忙做,即交给代理对象去做

 

2. 设计原则
首先得拥有某个代理对象属性
其次要很清楚代理有哪些方法
最后要保证能解耦

 

3. 实现方案
定义一个protocol,在其中声明一些和代理沟通的方法
拥有一个代理属性id<protocol> delegate
让代理遵守protocol
 
  1 //  2 //  main.m  3 //  05-protoco  4 //  5 //  Created by apple on 13-8-11.  6 //  Copyright (c) 2013年 itcast. All rights reserved.  7 //  8   9  10 /* 11  1.协议的定义 12  @protocol 协议名称 <NSObject> 13   // 方法声明列表.... 14  @end 15   16   17  2.如何遵守协议 18  1> 类遵守协议 19  @interface 类名 : 父类名 <协议名称1, 协议名称2> 20   21  @end 22   23  2> 协议遵守协议 24  @protocol 协议名称 <其他协议名称1, 其他协议名称2> 25   26  @end 27   28  3.协议中方法声明的关键字 29  1> @required (默认) 30    要求实现,如果没有实现,会发出警告 31   32  2> @optional 33    不要求实现,怎样不会有警告 34   35  4.定义一个变量的时候,限制这个变量保存的对象遵守某个协议 36  类名<协议名称> *变量名; 37  id<协议名称> 变量名; 38  NSObject<MyProtocol> *obj; 39  id<MyProtocol> obj2; 40   41  如果没有遵守对应的协议,编译器会警告 42   43  5.@property中声明的属性也可用做一个遵守协议的限制 44  @property (nonatomic, strong) 类名<协议名称> *属性名; 45  @property (nonatomic, strong) id<协议名称> 属性名; 46  47  @property (nonatomic, strong) Dog<MyProtocol> *dog; 48  @property (nonatomic, strong) id<MyProtocol> dog2; 49   50  6.协议可用定义在单独.h文件中,也可用定义在某个类中 51  1> 如果这个协议只用在某个类中,应该把协议定义在该类中 52   53  2> 如果这个协议用在很多类中,就应该定义在单独文件中 54   55  7.分类可用定义在单独.h和.m文件中,也可用定义在原来类中 56  1> 一般情况下,都是定义在单独文件 57  2> 定义在原来类中的分类,只要求能看懂语法 58  */ 59  60 #import <Foundation/Foundation.h> 61 #import "MyProtocol.h" 62 #import "MyProtocol3.h" 63 #import "Person.h" 64 #import "Dog.h" 65 #import "Hashiqi.h" 66  67 int main() 68 { 69     Person *p = [[Person alloc] init]; 70     p.obj = [[Hashiqi alloc] init]; 71      72     return 0; 73 } 74  75 void test() 76 { 77     //NSObject *obj = [[NSObject alloc] init]; 78      79      80     //NSObject *obj2 = @"4324324"; 81      82      83     // 要求obj3保存的对象必须是遵守是MyProtocol这个协议 84      85     //NSObject<MyProtocol> *obj3 = [[NSObject alloc] init]; 86      87     NSObject<MyProtocol> *obj3 = [[Person alloc] init]; 88      89     obj3 = nil; 90      91      92     id<MyProtocol> obj4 = [[Person alloc] init]; 93      94     obj4 = nil; 95      96     // 要求obj5,保存的对象必须遵守MyProtocol3、并且继承了Person 97     Person<MyProtocol3> *obj5 = [[Person alloc] init]; 98      99     obj5 = nil;100 }

代理设计模式

 1 // 2 //  main.m 3 //  07-协议的应用-代理模式 4 // 5 //  Created by apple on 13-6-30. 6 //  Copyright (c) 2013年 apple. All rights reserved. 7 // 8  9 #import <Foundation/Foundation.h>10 #import "Person.h"11 #import "Agent.h"12 #import "NextAgent.h"13 14 int main(int argc, const char * argv[])15 {16 17     @autoreleasepool {18         Person *p = [[[Person alloc] init] autorelease];19         20         NextAgent *a = [[[NextAgent alloc] init] autorelease];21         22         p.delegate = a;23         24         [p buyTicket];25     }26     return 0;27 }28 29 void test()30 {31     //32     Person *p = [[Person alloc] init];33     // 代理34     Agent *a = [[Agent alloc] init];35     36     // 设置人的代理37     p.delegate = a;38     39     // 人打算看电影40     [p buyTicket];41     42     [a release];43     [p release];44 }

 

黑马程序员——OC语言的Block与Protocol(协议)