------ <a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a> 期待与您交流! -------
分类(Category),代码块Block和
protocol代理设计模式学习总结
一.分类(Category)
1.类别的概念
Category有很多种翻译: 分类\类别\类目 (一般叫分类)
Category是OC特有的语法, 其他语言没有的语法(类似于C#语言中的”扩展方法”和”partial”关键字)
2.分类(Category)声明和实现
(1)声明和实现一个类别
在.h文件中,声明类别:
@interface ClassName (CategoryName)NewMethod; //在类别中添加方法
//不允许在类别中添加变量
@end
说明:
声明类别格式
1)新添加的方法必须写在 @interface 与
2)ClassName 现有类的类名(要为哪个类扩展方法)
3)CategoryName 待声明的类别名称
4)NewMethod 新添加的方法
注意:不允许在声明类别的时候定义变量
在.m文件中(也可以在.h中实现),实现类别:
@implementation ClassName(CategoryName)NewMethod
{
......
}
@end
说明:
实现类别格式
1)新方法的实现必须写在@ implementation与@end之间
2)ClassName 现有类的类名
3)CategoryName 待声明的类别名称
4)NewMethod 新添加的方法的实现
注:也可通过图形界面生成类别
(2)调用类别中的方法
与一般成员方法调用形式,完全一样需要包含类别的头文件
3.分类的使用注意事项
1)分类只能增加方法,不能增加成员变量@property(可能编译不报错,但是运行有问题)
2)分类可以访问原来类中的成员变量
3)如果分类和原来类出现同名的方法,优先调用分类中的方法,原来类中的方法会被忽略
注:分类的编译顺序为:最下面的是最后编译,当多个分类中有同名方法,则执行最后编译的文件方法
4.分类(Category)非正式协议
非正式协议就是给NSObject类创建的类目(分类)又叫做非正式协议,
非正式协议一般不需要进行实现,一般在子类中进行方法的重写。
(1)类的延展的概念
延展类别又称为扩展(Extendsion)
Extension是Category的一个特例其名字为匿名(为空),并且新添加的方法一定要予以实现。(Category没有这个限制)
@interface Student ()
@end
(2)延展的实现
通过延展来实现方法的私有,延展的头文件独立。这种方法不能实现真
正的方法私有,当在别的文件中引入延展的头文件,那么在这个文件中
定义的类的对象就可以直接调用在延展中定义所谓私有的方法
// 对类的延展 - 隐藏方法 wrap的一种手段(非强制).h文件
@interface SceneManager ()
+ (void) wrap;@end
.m类的实现文件中@implementation SceneManager+ (void) wrap {
NSLog(@"method of wrap");
}
@end
调用
[SceneManager wrap];// 这里会抱一个警告:Class method of "+ wrap" not found
// 不过虽然是警告,不过运行是正常的,不过这么写在自我规范上不好,
即使编译器没有做强制限制,我们自己也要限制自己。// 不然,延展方法就毫无意义可言。
注:还可通过界面创建延展
二.代码块Block
1.block的基本概念
Block对象是一个C级别的语法和运行机制。它与标准的C函数类似,
不同之处在于,它除了有可执行代码以外,它还包含了与堆、栈内
存绑定的变量。因此,Block对象包含着一组状态数据,这些数据在
程序执行时用于对行为产生影响。
你可以用Block来写一些可以传到API中的函数语句,可选择性地
存储,并可以使用多线程。作为一个回调,Block特别的有用,因
为block既包含了回调期间的代码,又包含了执行期间需要的数据。
由于Objective-C 和 C++ 都是衍生自 C,block被设计为可同时兼容这三种语言。
2.block的基本用法
用^操作符来声明一个Block变量,并指明Block述句的开始。Block的主体部分
包含在 {}内,像下面的例子中一样(与C语法一样,“;”指明语句的结束):
1) block最简单形式
定义格式:
void (^block名)() = ^{代码块;}
使用格式:
block名();
2) block带有参数的block的定义和使用格式:
void (^block名称)(参数列表)
= ^ (参数列表) { // 代码实现; }
3) 带有参数和返回值的block格式:
返回类型 (^block名称)(参数列表)
= ^ 返回类型 (参数列表) { // 代码实现; }
3.block的typedef
利用typedef定义block类型(和指向函数的指针很像)
格式:
typedef 返回值类型 (^block变量名)(参数类型列表);
Typedef int(^MyBlock)(int ,int);
速记符:以后就可以利用这种类型来定义block变量了。
4.block访问外部变量
5.block作为函数的返回值1)在block内部可以访问block外部的变量
在block内部可以变量,但是注意,这是一个新的内存空间变量
block内部也可以定义和block外部的同名的变量(局部变量),此时局部变量会暂时屏蔽外部变量的作用域
2)在block内部不可以修改block外部的变量
默认情况下,Block内部不能修改外部的局部变量
给局部变量加上__block关键字,则这个局部变量可以在block内部进行修改。
步骤:
1)使用typedef 定义一个新的类型
2)使用新类型作为函数的返回值
3)定义变量接收函数返回的值(block类型)
4)调用block
6.block使用技巧及注意
1) block 结构的快速提示利用
2) block变量用作方法的参数的时候最好把参数类型列表部分加上具体的形参名
1.protocol概念及基本使用
(1)protocol的基本概念
在写java的时候都会有接口interface这个概念,接口就是一堆方法
的声明没有实现,而在OC 里面,Interface是一个类的头文件的声明,
并不是真正意义上的接口的意思,在OC中,接口是由 一个叫做协议
的protocol来实现的。
这个里面可以声明一些方法,和java不同的是,它可以声明一些必须
实现的方法和选择实现 的方法。这个和java是完全不同的。
(2)protocol的使用流程
协议的使用流程:
定义协议----> 在类中采用指定的协议 ---->实现协议中的方法
(注意方法有必须实现和选择实现两种)
1)定义协议
协议的定义
@protocol 协议名称 <NSObject> //默认遵NSObject协议
//方法声明列表
@end;
注意: 协议默认的要采纳NSObject的协议
2)采纳协议
类遵守协议
创建类的时候遵守某个或者某几个协议
@interface 类名 : 父类 <协议名称> @end
//默认遵守NSObject协议
@interface 类名 : 父类 <协议名称1,协议名称2> @end
某个协议也遵守某个或者某些协议,一个协议可以遵守其他多个协议
1>协议遵守协议
@protocol 协议名称 <其他协议名称>
@end
2>多个协议之间用逗号 , 隔开。
@protocol 协议名称 <其他协议名称1, 其他协议名称2> @end
3)实现协议中的方法
2.protocol的基本使用
1)定义协议
协议的定义@protocol 协议名称 <NSObject>//方法声明列表@end;注意: 协议默认的要采纳NSObject的协议
2)采纳协议
注意:采纳协议要先把要采纳的协议引入过来
1>类遵守协议 : 某个类遵守某个协议
2>协议遵守协议
@protocol 协议名称 <其他协议名称> @end;
3)实现协议中的方法
如果一个类遵守了某个协议 则只需要在这个类的实现(.m)文件中,实现协议的方法就可以了
注:也使用图形界面创建协议
3.OC中的协议(protocol)使用注意:
1)Protocol:就一个用途,用来声明一大堆的方法(不能声明成员变量),不能写实现。
2)只要某个类遵守了这个协议,就拥有了这个协议中的所有方法声明。
3)只要父类遵守了某个协议,那么子类也遵守。
4)Protocol声明的方法可以让任何类去实现,protocol就是协议。
5)OC不能继承多个类(单继承)但是能够遵守多个协议。继承(:),遵守协议(< >)
6)基协议:<NSObject>是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。
7)协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明
注: 1)协议之间可以有继承关系
2)类如果采纳协议后,实现了协议的方法,这些方法可以被子类继承
4.protocol基协议介绍
NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它,它
还有名字也叫 NSObject的协议,它是一个基协议,最根本最基本的协议
NSObject协议中声明很多最基本的方法 description
retain
release
建议每个新的协议都要遵守NSObject协议
5.protocol中@required和@optional
@required和@optional是协议方法声明中的两个关键字他们主要用于控制方法
是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流
@public
@protected
@private
@package
@required:这个方法必须要实现(若不实现,编译器会发出警告)
@optional这个方法不一定要实现
6. protocol类型限制
1)使用id存储对象时,对象的类型限制
格式:id <协议名称> 变量名
2)对象赋值时类型限制 使用类也同样如此
格式:类名<协议名称> *变量名
3)对象关联关系下,对象的类型限制
7.id和instancetype的区别
id和instancetype的区别:
1)instancetype只能作为函数或者方法的返回值
2)id能作为方法或者函数的返回值、参数类型,也能用来定义变量
3)instancetype对比id的好处
* 能精确地限制返回值的具体类型
8.protocol代理设计模式引入
代理模式是在oc中经常遇到的一种设计模式,那什么叫做代理模式呢?
举个例子:有一个婴儿,他本身不会自己吃饭和洗澡等等一些事情,于
是婴儿就请了一个保姆,于是婴儿和保姆之间商定了一个协议,协议
中写明了保姆需要做什么事情, 而保姆就是这个代理人, 即:婴儿和
保姆之间有个协议,保姆遵守该协议,于是保姆就需要实现该协议中
的条款成为代理人。
9. protocol代理设计模式概念
代理模式概念
传入的对象,代替当前类完成了某个功能,称为代理模式
利用协议实现代理模式的主要思路为:
1)定义一个协议,里面声明代理类需要实现的方法列表,
比如这里一个代理类需要实现feedBaby与HongSleep方法
2)创建一个代理类(比如BaoMu),遵守上面的代理协议
3)在需要代理的类中(Baby),定义一个对象类型为id且遵守代理协议的成员变量
4)在Baby类中调用成员变量_delegate(代理)的方法,调用代理类的方法
5)main.m或其他使用Baby类的文件中,为Baby类的成员变量(代理类)赋值
10.protocol代理模式应用场合
代理设计模式的场合: * 当对象A发生了一些行为,想告知对象B
(让对象B成为对象A的代理对象) * 对象B想监听对象A的一些行
为(让对象B成为对象A的代理对象) * 当对象A无法处理某些行为
的时候,想让对象B帮忙处理 (让对象B成为对象A的代理对象)
1)监听器的场合 * Teacher想监听Baby的一些行为2)通知的场合 * Baby发生了一些行为,想告知Teacher3)有些事情,不想自己处理,想交给别人处理 * Baby发生了一些
行为, 但是自己不会处理, 可以交给Teacher处理