OC 下的 NSProxy 与 JS 下的 Proxy 简单应用场景

669 阅读3分钟

废话开篇:对于 iOS 下的代理,一般都会想到 delegate,比如最常用的 UITableView 的delegate,这里代理的作用就方便开发者去调用自身类以外的某些方法,来实现某些的业务场景下的通信。在 OC “消息转发”的大环境下,NSProxy 代理类为开发者提供了更多的角度思路来处理代码逻辑。JS 下的 Proxy 也是代理,Vue2.0 实现双向绑定用的还是 defineProperty 属性的声明来重写 set get 方法,Vue3.0 便利用了 Proxy 代理 set get 方法来双向绑定。下面就看看这 OC 下的 NSProxy 与 JS 下的 Proxy 的简单的应用场景。

场景一、 OC 下的 NSProxy

OC 下的 NSProxy 利用的是消息转发机制,大致的的意思就是:OC 语言会给一个对象调用的本类找不到方法提供一些额外的判断,比如:是否去执行本类的其他方法,是否可以让其他实例对象执行当前找不到的方法...最后,仍然没有处理这条消息,那么,崩溃。

这里创建 WSLProxy 代理类

image.png

这里创建 Person 类

image.png

让代理执行一个方法,通过消息转发发送给代理对应下的 target 去执行。

image.png

这时候,代理的就会把 lookAtMine: 方法进行转发,最后在代理类的 forwardInvocation 方法里处理消息。

image.png

这里有个注意的地方,当 WSLProxy 的target 用 weak 修饰的时候,在消息转发的时候很可能会释放掉,所以,没有指定对象去处理方法签名后,当前的代理类的消息转发就此结束,崩溃了,因此,这里需要用 strong 修饰,注意的是:定时器下的 target 必须要用 weak 修饰,防止强引用链穿到类似 UIViewController 等作为真正执行定时器任务的对象。

image.png

定时器的释放问题的处理,此时的 WSLProxy 的target 必须用 weak 修饰

image.png

在 UIViewController 的 dealloc 里面进行定时器的释放。

image.png

在执行 pop 方法后,控制器销毁了

image.png

场景二、 JS 下的 Proxy

这里简单的实现一下基于 uniapp 的网络请求的切面写法,一般 uniapp 的网络请求是通过 uni.request 方法实现的,那么,就 代理一下这个 request 方法,拓展中间件,实现统一加载提示框。

//导出模块
export default new Proxy({}, {
	get(target, name) {
                //返回方法,方法参数是网络请求参数,方法的返回值是异步对象
		return (obj) => new Promise((resolve, reject) => {
			obj.url = 'baseuUrl' + obj.url;
			obj.header = Object.assign({
				"Content-Type": 'application/json',
			}, obj.header);
                        //请求前展示加载视图
			uni.showLoading({
				title: '加载中',
				mask: true
			})
                        //这里等同于 uni.request() 方法调用
			uni[name]({
				...obj,//网络请求参数
				success: ret => {
                                        //网络请求完成
					if (ret.statusCode == 200 || ret.data.code === 200) {                        
                                                //成功回调
						resolve(ret.data)
					} else {
                                                //提示错误信息
						uni.showToast({
							title: ret.data.message,
							icon: 'none'
						})
                                                //报错警告
						reject(ret.data)
					}
				},
				fail: err => {
                                        //报错警告
					reject(err)
				},
				complete: () => {
                                        //隐藏加载视图
					uni.hideLoading()
				}
			})
		}).catch((e) => {
                        //catch
			console.log(e)
		})
	}
})

方法的调用,这里直接用对象调用了 request 方法,在代理的 get 方法里直接进行了 uni 的 request 方法。

HTTP.request({
'url':'12',
}).then(result=>{
})

好了,上面是极其简单的 OC 下的 NSProxy 与 JS 下的 Proxy 简单应用场景,面对复杂的开发业务逻辑,还是要选择合适的开发模式。

思路笔记,大神勿笑。