您的位置:首页 > 职场人生

黑马程序员-@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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  protocol block