扩展(Extension)
一般用扩展来做什么?
1.声明私有属性
,是可以不对子类暴露的。
2.声明私有方法
,方便阅读。
3.声明私有成员变量
。
扩展的特点:
1.编译时
决议。
2.只以声明的形式存在
,没有具体实现,多数情况寄生于宿主类的.m中,也就是说,它不是独立存在实现的一个文件,可以把扩展理解为类的一个内部的私有声明。
3.不能为系统类添加扩展。
分类和扩展的区别:
1.分类是运行时决议,扩展是编译时决议。
2.分类可以有声明有实现,而扩展只有声明,它的实现是直接写在宿主类当中。
3.可以为系统类添加分类,但不能为系统类添加扩展。
代理(Delegate):
什么是代理:
1.准确的说是一种软件设计模式,代理模式.
2.iOS当中以@protocol形式体现.
3.传递方式是一对一.
代理的工作流程:
1.委托方会要求代理放需要实现的接口,全部定义在协议当中。
2.在协议当中可以声明属性,也可以声明方法。
3.代理会按照协议实现方法。
4.代理会返回一个处理结果给委托方。
5.委托方需要调用代理方遵从的协议方法。
首先定义一个协议类,来定义公共协议
#import
@protocol LoginProtocol
@optional
- (void)userLoginWithUsername:(NSString *)username password:(NSString *)password;
@end
定义委托类,这里简单实现了一个用户登录功能,将用户登录后的账号密码传递出去,由代理来处理具体登录细节。
#import
#import "LoginProtocol.h"
/**
* 当前类是委托类。用户登录后,让代理对象去实现登录的具体细节,委托类不需要知道其中实现的具体细节。
*/
@interface LoginViewController : UIViewController
// 通过属性来设置代理对象
@property (nonatomic, weak) id delegate;
@end
实现部分:
@implementation LoginViewController
- (void)loginButtonClick:(UIButton *)button {
// 判断代理对象是否实现这个方法,没有实现会导致崩溃
if ([self.delegate respondsToSelector:@selector(userLoginWithUsername:password:)]) {
// 调用代理对象的登录方法,代理对象去实现登录方法
[self.delegate userLoginWithUsername:self.username.text password:self.password.text];
}
}
代理方,实现具体的登录流程,委托方不需要知道实现细节。
// 遵守登录协议
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
LoginViewController *loginVC = [[LoginViewController alloc] init];
loginVC.delegate = self;
[self.navigationController pushViewController:loginVC animated:YES];
}
/**
* 代理方实现具体登录细节
*/
- (void)userLoginWithUsername:(NSString *)username password:(NSString *)password {
NSLog(@"username : %@, password : %@", username, password);
}
这里我们需要知道一下,协议中可以定义哪些内容?协议可以通过@required定义必须实现的代理方法,通过@optional定义可选方法。
在我们实际开发中,委托方和代理方的关系应该怎么样建立,他们建立的关系的过程中,应该注意哪些问题?
在使用代理的时候,存在一个循环引用的问题
,当代理,协议,委托都通过强引用(strong)形成一个闭环,则会造成内存泄露的问题,此时我们通常会让委托方弱(weak)引用指向代理方来避免循环引用。
通知(NSNotification)
- 使用观察者模式来实现的、用于跨层传递消息的机制(一般数据处理逻辑是网络层传递到数据层,然后在经过业务逻辑层加工再去更新UI。如果有时候网络层返回的数据不经过业务逻辑层,直接到达UI层,这时候就用到跨层传递)。
- 传递方式为一对多。
通知和代理的区别:
- 通知是观察者模式来实现,代理是由代理模式实现的。
- 通知传递方式是一对多。代理是传递方式是一对一。
如何实现通知机制?
首先,信息的传递就依靠通知(NSNotification),也就是说,通知就是信息(执行的方法,观察者本身(self),参数)的包装。通知中心(NSNotificationCenter)是个单例,向通知中心注册观察者,也就是说,这个通知中心有个集合,这个集合存放着观察者。
那么这个集合是什么样的数据类型 ? 大概猜想: 发送通知需要name参数,添加观察者也有个name参数,这两个name一样的时候,当发送通知时候,观察者对象就能接受到信息,执行对应的操作。猜想这个集合是NSDictionary
。
key就是name,value就是NSArray(存放数据模型),里面存放观察者对象。如下图