黑马程序员——10、OC语言(block、protocol和代理模式)
2014-10-23 17:25
387 查看
---------------------- Java培训、Android培训、iOS培训、.Net培训,期待与您交流!
---------------------
block可以作为函数参数或函数的返回值,而其本身又可以带输入参数和返回值。
* block在程序运行时确定
block用来保存一端代码
block的标示:^
* block跟函数很像:
》可以保存代码
》有返回值
》有形参
》调用方式一样
1.如何定义block变量
int (^sumBlock)(int, int);
return a+b;
};
* 默认情况下,block【不可以修改】外面的局部变量
* 给局部变量加上__block修饰,这个局部变量就可以在block中修改
以后可以利用MyBlock这种类型定义block变量
MyBlock b1;
b1 = ^(int a, int b){
return 12;
}
: 继承父类(OC单继承)
<> 遵守协议(协议多遵守)
() 分类
// 方法声明列表
@end
@interface 类名 : 父类名 <协议名称1, 协议名称2>
@end
2》协议遵守协议
@protocol 协议名称 <其他协议名称1, 其他协议名称2>
@end
一个协议遵守了另一个协议,就可以拥有另一个协议的所有方法声明。
要求实现。若不实现,则发出警告<
4000
/span>
2》@optional
不要求实现
只要一个类遵守了某个协议,就能拥有这份协议的所有方法声明。
NSObject是一个基类,同时也有个NSObject的基协议,基协议里有很多最基本的方法,比如:description、retain、release等。
建议每一个新的协议都遵守NSObject协议。
id<协议名称> 变量名;
如果没有遵守对应的协议,编译器会警告(比较严重的)
@property (nonatomic, strong) id<协议名称> 变量名;
2》如果这个协议用在很多类中,就应该定义在单独.h文件中
2》也可以定义在原来类中,只要求能看懂语法
但是在实现文件.m中,还是要#import引入这个协议的.h文件。跟@class相同。
需要代理方具有协议里面的方法,才能实现请求方的代理需求。
设计原则:
》先让某个对象属性拥有代理权利
》清楚代理协议里的方法
》要保证能解耦
实现方法:
》先定义一个protocol,在其中声明一些和代理沟通的方法
》拥有一个代理属性 id<protocol> delegate;
》让代理类遵守这个协议protocol
Person.m
Agent.m
---------------------
一、block
block封装了一段代码,可以在任何时候执行。block可以作为函数参数或函数的返回值,而其本身又可以带输入参数和返回值。
* block在程序运行时确定
block用来保存一端代码
block的标示:^
* block跟函数很像:
》可以保存代码
》有返回值
》有形参
》调用方式一样
1.如何定义block变量
int (^sumBlock)(int, int);
2.如何利用block封装代码
^(int a, int b){return a+b;
};
// 如果block没有形参,^() 可以省略() // 定义block变量 void (^myblock)() = ^{ NSLog(@"+++++++++++++++"); NSLog(@"---------------"); }; // 利用block变量调用block内部代码 myblock();
// 用一个block输出n条横线 void (^lineBlock)(int) = ^(int n){ for (int i=0; i<n; i++) { NSLog(@"-------------"); } }; lineBlock(4);
3.block访问外部变量
* block可以直接访问外部变量* 默认情况下,block【不可以修改】外面的局部变量
* 给局部变量加上__block修饰,这个局部变量就可以在block中修改
__block int i = 10; MyBlock printBlock = ^(int v1, int v2){ i++; // 可以修改局部变量了 NSLog(@"a=%d", i); return v1+v2; }; int f = printBlock(12, 13); NSLog(@"%d", f);
4.利用typedef定义block类型
typedef int (^MyBlock)(int, int);以后可以利用MyBlock这种类型定义block变量
MyBlock b1;
b1 = ^(int a, int b){
return 12;
}
// 指向函数的指针 定义为 SumP类型 typedef int (*SumP)(int, int); // block 定义为 MyBock类型 typedef int (^MyBlock)(int, int);
SumP p = sum; int c = p(10, 15); NSLog(@"%d", c); MyBlock sumBlock = ^(int a, int b){ return a+b; }; int d = sumBlock(10, 15); NSLog(@"%d", d); MyBlock minusBlock = ^(int a, int b){ return a-b; }; int e = minusBlock(10, 15); NSLog(@"%d", e);
5. block与指向函数的指针
// block int (^sumblock)(int, int) = ^(int a, int b){ return a+b; }; int res = sumblock(10, 12); NSLog(@"%d", res); /********************************/ //指向函数的指针 int (*p)(int, int) = sum; int c = p(10, 11); NSLog(@"%d", c);
二、protocol
一系列方法的声明。: 继承父类(OC单继承)
<> 遵守协议(协议多遵守)
() 分类
1. 协议的定义
@protocol 协议名称 <NSObject>// 方法声明列表
@end
2. 如何遵守协议
1》类遵守协议@interface 类名 : 父类名 <协议名称1, 协议名称2>
@end
2》协议遵守协议
@protocol 协议名称 <其他协议名称1, 其他协议名称2>
@end
一个协议遵守了另一个协议,就可以拥有另一个协议的所有方法声明。
3. 协议方法中声明的关键字
1》@required(默认)要求实现。若不实现,则发出警告<
4000
/span>
2》@optional
不要求实现
只要一个类遵守了某个协议,就能拥有这份协议的所有方法声明。
NSObject是一个基类,同时也有个NSObject的基协议,基协议里有很多最基本的方法,比如:description、retain、release等。
建议每一个新的协议都遵守NSObject协议。
// 定义了一个名叫MyProtocol的协议 @protocol MyProtocol <NSObject> // 默认@required - (void)test4; @required - (void)test1; - (void)test2; @optional + (void)test3; @end
4. 定义一个变量的时候,限制这个变量保存的对象遵守某个协议
类名<协议名称> *变量名;id<协议名称> 变量名;
如果没有遵守对应的协议,编译器会警告(比较严重的)
// 要求obj2保存的对象必须是遵守MyProtocol这个协议 // Person 已经遵守了MyProtocol这个协议,没有警告 NSObject<MyProtocol> *obj2 = [[Person alloc] init]; obj2 = nil; id<MyProtocol> obj3 = [[Person alloc] init]; obj3 = nil; // 要求obj4,保存对象必须遵守MyProtocol3,并且继承Person Person<MyProtocol3> *obj4 = [[Person alloc] init]; obj4 = nil;
5. @property中声明的属性也可以用来声明一个遵守协议的限制
@property (nonatomic, strong) 类名<协议名称> *变量名;@property (nonatomic, strong) id<协议名称> 变量名;
6. 协议可以定义在单独.h文件中,也是定义在某个类的文件中
1》如果这个协议用在某个类中,应该把协议定义在这个类中2》如果这个协议用在很多类中,就应该定义在单独.h文件中
7. 分类可以定义在单独.h和.m文件中,也是定义在原来类中
1》一般情况下,都是定义在单独文件中2》也可以定义在原来类中,只要求能看懂语法
8. 声明某个字符串是一个协议
@protocol 协议名;但是在实现文件.m中,还是要#import引入这个协议的.h文件。跟@class相同。
三、代理模式
请求方 —— 协议 —— 代理方需要代理方具有协议里面的方法,才能实现请求方的代理需求。
设计原则:
》先让某个对象属性拥有代理权利
》清楚代理协议里的方法
》要保证能解耦
实现方法:
》先定义一个protocol,在其中声明一些和代理沟通的方法
》拥有一个代理属性 id<protocol> delegate;
》让代理类遵守这个协议protocol
(1)Person类的声明与实现
Person.h#import <Foundation/Foundation.h> @protocol TicketDelegate; @interface Person : NSObject // 拥有一个代理属性 // 代理类名随便,但必须遵守TicketDelegate协议 @property (nonatomic, strong) id<TicketDelegate> delegate; - (void)wantMoive; @end
Person.m
#import "Person.h" #import "TicketDelegate.h" @implementation Person - (void)wantMoive { NSLog(@"xiang看电影"); // 叫代理去帮自己买票 double price = [_delegate ticketPrice]; int number = [_delegate leftTickets]; NSLog(@"通过代理,票价:%f,剩余票数:%d", price, number); } - (void)dealloc { NSLog(@"Person dealloced!!"); } @end
(2)代理协议(谁遵守了这个协议,谁就可以做代理)
TicketDelegate.h#import <Foundation/Foundation.h> // 声明一些跑腿的方法 @protocol TicketDelegate <NSObject> // 返回票价 - (double)ticketPrice; // 剩余票数 - (int)leftTickets; @end
(3)Agent类的声明与实现
Agent.h#import <Foundation/Foundation.h> #import "TicketDelegate.h" @interface Agent : NSObject <TicketDelegate> //// 返回票价 //- (double)ticketPrice; // //// 剩余票数 //- (int)leftTickets; @end
Agent.m
#import "Agent.h" @implementation Agent - (double)ticketPrice { // ...查票价 return 1; } - (int)leftTickets { // ...查票数 return 1000; } @end
(4)运行代理
Person *p = [[Person alloc] init]; // 代理 Agent *a = [[Agent alloc] init]; // 设置人的代理 p.delegate = a; // 人打算看电影 [p wantMoive];
相关文章推荐
- 黑马程序员——OC语言——block、protocol、代理模式
- 黑马程序员——OC语言------Block、protocol协议、代理设计
- OC-10-其他:block、protocol、代理设计模式
- 黑马程序员——入学Blog05----OC的protocol与代理模式
- OC_语法入门_day6_ARC(循环引用)/block代码块(闭包)/protocol协议(接口)/代理模式
- 黑马程序员————OC语言BLOCK和Protocol总结
- 黑马程序员——OC语言之代理模式
- OC语言 block 和 代理模式
- Oc语言之Protocol代理设计模式
- 黑马程序员——OC语言学习——ARC机制、block代码块、protocol协议、protocol协议的应用
- 黑马程序员——OC基础学习(五)---分类(Category),代码块Block和protocol代理设计模式
- 黑马程序员——OC学习——Protocol和代理设计模式
- 黑马程序员——OC语言基础篇---block和protocol
- ObjectC语言基础1—block、protocol、代理设计模式
- 黑马程序员 _10 OC基础 block 协议 代理
- 黑马程序员之ios学习总结——10 OC语言的构造方法和分类
- 黑马程序员_OC学习之block、protocol、categories
- 黑马程序员--oc:block与protocol
- OC语言BLOCK和Protocol总结
- 黑马程序员——protocol的基本使用和代理设计模式