现在的位置: 首页 > 综合 > 正文

object-c编程tips-给类对象添加属性

2018年03月22日 ⁄ 综合 ⁄ 共 1409字 ⁄ 字号 评论关闭

此问题来源于网络封装的一个内容,由于保密的问题,我只叙述我业余的一些想法。

基本思想:

网络请求大家应该都会用一个基类的BaseNetWork, 然后由派生类继承于BaseNetWork,并实现一些特殊的方法。 一般标准的流程是传入block, 当网络请求完毕后,通过block回调回来。这里叙述的关键不是如何实现一个网络请求和回调block的相关内容,而是如何取消请求。 一般基类会实现一个cancelNetWork方法,它根据自己的url进行cancel操作。 

举例:

我们使用 DerivedNetWork* net = [DerivedNetWork alloc]init]; 在init方法中设置了自身的url,然后调用基类的sendRequest发送请求, 等待网络返回的回调。 如果需要取消请求,难道我们使用[net CancelNetWork];,这样肯定不好。 毕竟在其他的方法里面不能得到当前的net指针,保存成成员又没有必要。
于是大家会想到应该使用类名进行cancel操作。 即将cancelNetWork定义成类方法,而不是对象方法。 这就引入了一个新的问题, 类方法如何获取到对象的url? 经过苦思冥想,有一天发现了objc_setAssociatedObject方法,又联想到类对象本身也是对象的思路,想到一个解决方案。

方案:

基类NetWork类的实现代码:

#define LSPerson_URL_Key @"LSPerson_URL_Key"

@implementation BaseNetWork

-(void)setUrl:(NSString *)url
{
    objc_setAssociatedObject([self class], LSPerson_URL_Key, url, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
+(void)cancelRequest
{
    NSString* url =  objc_getAssociatedObject([self class], LSPerson_URL_Key);
    NSLog(@"cancelRequestUrl:%@", url);
}
@end

上面基类有一个setUrl方法,供派生类的对象使用设置自身的url, 它将url绑定到self class的类对象上。 然后还有一个cancelRequest类方法,它从当前类对象中读取到url,来进行真正的cancel操作。 通过这种方式,派生类可以使用此类方法进行自由的取消请求操作了。

代码:

LPStudyRequest* lpReq = [[LPStudyRequest alloc]init];
lpReq.url = @"http://jiawei.com";

//可以看到日志的输出,不同的派生类可以得到不同的url。再使用此url传递给AF进行取消操作。
[LPStudyRequest cancelRequest];


总结:

上面是一个基本的给类添加变量的思想。 它在这个取消网络请求里面得到了很好的应用。 我还将它用到防止自身提前释放, 仿C++的静态变量中。

请一定要注意: C++的静态变量和object-c里面用到的单例static是不一样的。 一个是属于类的静态变量,一个是属于全局程序的静态变量。 如果基类定义了静态变量,派生类继承的话, C++的派生类会很好的继承下来, OC的所有的派生类对象公有的是同一个内存, 因此可以考虑使用绑定到类对象中模拟这种情况。

抱歉!评论已关闭.