黑马程序员-@protocol协议代理与block代码块
2016-01-10 10:49
453 查看
</pre><h5><p><span style="color: rgb(51, 51, 51); font-family: Arial; font-size: 18px; line-height: 26px;">------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------</span></p></h5><h5><span style="font-size:18px;">一、@protocol关键字的应用</span></h5><pre>
<pre name="code" class="html">// Person.h // 07协议的应用-代理模式
// // Created by 黄焕恩 on 16/1/5. // Copyright © 2016年 黄焕恩. All rights reserved. // #import <Foundation/Foundation.h> #import "AgentDelegate.h" @interface Person : NSObject @property (nonatomic,strong) id<AgentDelegate> agent; // 这里声明让Person拥有agent,id类型随便,当多个代理的时候 就不用再去修改代码。还有就是如果不用协议的话就会报错,因为id的类型是不确定的,agent 不知道去哪找。但是当遵守协议之后,自然就可以去协议那里找方法声明了。
- (void)buyTicket;@end
</pre><p></p><p></p><p></p><pre code_snippet_id="1552998" snippet_file_name="blog_20160110_3_5468146" name="code" class="html">// // Person.m // 07协议的应用-代理模式 // // Created by 黄焕恩 on 16/1/5. // Copyright © 2016年 黄焕恩. All rights reserved. // #import "Person.h" @implementation Person - (void)buyTicket // 说出需求,让代理去做就好,这就是面向对象的思想 { int a = [_agent leftTicketsNumber1]; double b = [_agent ticketPrice1]; NSLog(@"剩余的票数是%d,票的价格是%f",a,b); } @end
</pre><pre name="code" class="html">代理一:实现的功能是去买票,返回票价和票数给Person。
<pre name="code" class="html">// // Person.m // 07协议的应用-代理模式 // // Created by 黄焕恩 on 16/1/5. // Copyright © 2016年 黄焕恩. All rights reserved. // #import "Person.h" @implementation Person - (void)buyTicket { int a = [_agent leftTicketsNumber1]; double b = [_agent ticketPrice1]; NSLog(@"剩余的票数是%d,票的价格是%f",a,b); } @end
// // Agent.m // 07协议的应用-代理模式 // // Created by 黄焕恩 on 16/1/5. // Copyright © 2016年 黄焕恩. All rights reserved. // #import "Agent.h" @implementation Agent - (int)leftTicketsNumber1 { return 1; } - (double)ticketPrice1 { return 29; } @end
代理2的功能与代理1一样:
<p style="margin-top: 0px; margin-bottom: 0px; font-size: 18px; font-family: Menlo; color: rgb(29, 148, 33);"></p><pre name="code" class="html">
// // NextAgent.h // 07协议的应用-代理模式 // // Created by 黄焕恩 on 16/1/5. // Copyright © 2016年 黄焕恩. All rights reserved. // #import <Foundation/Foundation.h> #import "AgentDelegate.h" @interface NextAgent : NSObject<AgentDelegate> @end
// // NextAgent.m // 07协议的应用-代理模式 // // Created by 黄焕恩 on 16/1/5. // Copyright © 2016年 黄焕恩. All rights reserved. // #import "NextAgent.h" @implementation NextAgent - (int)leftTicketsNumber1 { return 0; } - (double)ticketPrice1 { return 59; } @end
@protocol协议只是提供了类的方法声明,并没有实现实现
// // AgentDelegate.h // 07协议的应用-代理模式 // // Created by 黄焕恩 on 16/1/5. // Copyright © 2016年 黄焕恩. All rights reserved. // #import <Foundation/Foundation.h> @protocol AgentDelegate <NSObject> - (int)leftTicketsNumber1; - (double)ticketPrice1; @end
总结:代理指的是:一系列方法的列表,声明的方法可以被任何类实现。@protocol在声明的时候用到两个关键字:@required和@optional,@required声明的方法必须要实现,而optional声明的方法可实现,可不实现。代理模式(delegrate)的好处:一是减少代码的耦合性,因为协议只是声明了方法,具体的实现让代理去做,每个代理都是独立的。二是在多个类中,如果实现的方法都是一样的,那么用协议就可以大大减少代码的改动。
三是@protocol只是声明了方法,只要遵守该协议的,就可以拥有这个方法,并去实现这个方法。
比较扩展:
1>Protocol只是声明了方法,任何类只要遵守这个协议,都可以去实现。如果一个方法需要被多个不同类去实现的话,用protocol实现比较好。
2>Category是在不改变原类模型下对该类的方法进行补充。Category可以按不同的功能将类的实现分在不同的模块中实现。如果分类中的方法与原始类方法一样,将会把原始类的方法覆盖掉。如果有多个分类,执行的时候是按照分类在编译器的前后来进行的。
3>继承都可以完成上面的工作,但是通过继承来进行方法扩展,一是耦合很高的行为,对父类可以说是完全依赖;二是继承由于 对父类依赖,所以开发代价相对大,要求对父类的工作流程相对熟悉;三是继承体系如果太复杂会导致整个系统混乱,难以维护。所以在能够用上面两种方法完成扩
展的时候,就千万不要使用继承。什么情况才是迫不得已要使用继承呢?那就是如果你既想提供一系列接口的定义,同时又想提供一些但是又不能提供全部的实现的 时候,这种情况就要使用继承了。所以这么看来继承是对上面两种功能的一个黏合剂。
二、block的使用
代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值。
脱字符(^)是块的语法标记。按照我们熟悉的参数语法规约所定义的返回值以及块的主体(也就是可以执行的代码)。下图是如何把块变量赋值给一个变量的语法讲解:
<span style="font-family: Arial; font-size: 14px; line-height: 26px;">按照调用函数的方式调用块对象变量就可以了:int a = myblock(10);</span>
typedef void (^lineBlock)(int); int main()
{ int a = 10; __block int b = 20; // block 内部都可以访问外部的局部变量 void (^blcok)()=^{ a = 15; // a不是block类型,只能被使用,不能被修改 b = 25; // b是block类型,可以使用和修改外部的局部变量 NSLog(@"a=%d ,b=%d",a,b); }; blcok(); int (^myBlock)(int, int) = ^(int a,int b) { return a+b; }; // 相当于赋值语句,需要加分号。 int a = myBlock(12,10); void (^lineBlock)(int) = ^(int n) { for (int i = 0; i < n ; i++) { NSLog(@"---------"); } }; lineBlock printNLine = ^(int n) // lineBlock 是类型名, printNLine是block变量,当然是给变量赋值啦 { for (int i = 0 ; i < n ; i++) { NSLog(@"-----"); } }; return 0; }
相关文章推荐
- Ruby中Block和迭代器的使用讲解
- Ruby中使用Block、Proc、lambda实现闭包
- Ruby中的block、proc、lambda区别总结
- Protocol Buffer技术深入理解(C++实例)
- 全面解析Objective-C中的block代码块的使用
- block 实现原理详解(一)
- Some Notes of Protocol Buffer C++
- iOS页面传值总结
- ios高效开发二--ARC跟block那点事
- cocos2d里面如何实现MVC(二)
- cocos2d里面如何实现MVC(五)
- EOP / Office 365: Block or Allow IP Address in Connection Filtering
- 微信公众平台开发 OAuth2.0网页授权认证
- 802.1x技术介绍
- VTUN(vtun.sourceforge.net)
- AF_PACKET套接字解密
- objective-c block 讲解
- rsync 错误与解决方案收集
- rsync常见错误