------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、Block
- Block封装了一段代码,可以在任何时候执行
- Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值
- 苹果官方建议尽量多用block。在多线程、异步任务、集合遍历、集合排序、动画转场用得很多。
- 函数是在编译时就是运行之前就要定义好,代码被定义死,block可以在程序运行过程中产生。。
- block内存管理,有时候在堆里,有时候在栈里。
- block用来保存一段代码跟函数很像
- 可以保存代码
- 有返回值
- 有形参
- 调用方式一样
<span style="font-family:SimHei;font-size:18px;">//定义一个没有参数没有返回值的block
void (^myblock)() = ^{
NSLog(@"111");
};
//利用block变量利用block代码
myblock();</span>
定义格式:先定义block类型变量,然后把代码块给他。
返回值 (^block变量名)(形参1,形参2)= ^(形参1,形参2)
{
代码;
返回值;
};(这里千万别忘了分号)
如果block没有形参,可以省略后面的小括号。
下面是一个完整的block定义和调用
<span style="font-family:SimHei;font-size:18px;">int (^sumBlock)(int, int) = ^(int a, int b)
{
return a + b;
};
sumBlock(1, 3);</span>
下面看看函数指针
int sum(int a, int b)
{
return a + b;
}
int (*p)(int, int) = sum;
p(3,4);
使用typedef来给上面的函数指针定义一个别名
typedef int(*SumPoint)(int,int);
然后调用它
sumPoint p2 = sum;
p2(2,3);
所以block也可以用typedef来定义一个别名
typedef int(^SumBlock)(int a,intb);
调用
sumBlock sumBlock = ^(inta, int b)
{
returna + b;
};
sumBlock(1, 3);
- block可以直接访问外面的变量
- 默认情况下,block内部不能修改外部的变量
- 给局部变量加上__block关键字,这个局部变量就可以在block内部修改。
二、协议@protocol
作用:
- @protocol就是声明一大堆方法,和分类一样不能声明成员变量。只有.h文件。
- 只要某个类遵守了这个协议,就相当于这个类拥有了所有的方法声明。
- 只要父类遵循了这个协议,也代表子类也遵守了。
格式:
#import <Foundation/Foundation.h>
@protocol MyProtocol <NSObject>
- (void)test1;
- (void)test2;
@end
类遵守协议格式:只要一个类,遵守了谋一份协议,就能拥有了这份协议中的方法声明。
#import <Foundation/Foundation.h>
#import "MyProtocol.h"//必须要包含协议文件
@interface Person : NSObject <MyProtocol>//尖括号代表遵守协议。
@end
协议中的关键字:
默认协议定义的声明都是必须实现的也就是关键字@required。表示它声明的方法,在遵循着里都必须实现。不实现就会发出警告。
还有一个@optional,他表示它下面的声明的方法实现都是可选的。不实现也没差。
类只能继承一个父类,可以遵守多个协议。
协议主要用在代理模式和观察者模式中。
协议和类一样,类有基类,协议也有基协议
@protocol MyProtocol <NSObject>
上面表示协议遵循了基协议NSObject,任何协议最好都继承基协议。NSObject。
从上得知,协议也可以遵守其他协议。就包含了其他协议的所有声明。
如果协议3遵循协议1,一个类想遵守它们俩的话,需要遵守协议3就可以了。因为协议3里面已经遵守了协议1.
限制对象类型:在对象类型后面加上协议来限制指针的指向对象。
//普通新建对象
NSObject *obj1 = [[NSObject alloc]init];
//多态语法
NSObject *obj2 = @"123";
//因为任何对象都是继承自NSObject基类的,所以任何对象都可以把地址给一个NSObject类型的指针。多态
//现在我向左一个限制,限制一个NSObject类型指针只能存储一个遵循了<MyProtocol>协议的对象。如果把一个未遵守协议的对象给他,就会产生警告。
NSObject<MyProtocol>*obj3 = [[NSObject alloc]init];
}
同@class作用一样,协议也有一个关键字@protocol来提高性能。
有了这个就不用#import了。但必须的在.m文件中#import协议文件。
设计模式小贴士
当一个协议,只在一个类中使用,就写在类里面
当一个协议,很多类都要遵守,就写在外面
分类也一样。很少方法或者只一个类使用,可以把分类的声明和实现,分别写在类中。