俄罗斯贵宾会-俄罗斯贵宾会官网
做最好的网站

iOS Runtime特性之关联对象

引言:最近在工作中遇到与某些API对接的post的数据需要将对象的字段首字母小写。
解决办法有两种:
第一种:使用对象的字段属性设置JsonProperty来实现(不推荐,因为需要手动的修改每个字段的属性)

前言

现在你准备用一个系统的类或者是你写的类,但是这个类并不能满足你的需求,你需要额外添加一个属性。一般解决办法要么是extends,要么使用category。而我并不推荐使用extends,主要是耦合性太强,一般我使用category。我们都知道,分类中是无法设置属性的,如果在分类的声明中写@property 只能为其生成get 和 set 方法的声明,但是有时候使用类别也需要增加一个额外属性,那么怎么办呢?这个时候,runtime的关联属性就能发挥它的作用了。一般都是key value 的存在。

public class UserInfo
{
    [JsonProperty("id")]
    public int Id{ set; get; }
    [JsonProperty("userName")]
    public string UserName{ set; get; }
}

有关的方法

objc_setAssociatedObject 设置关联对象使用objc_getAssociatedObject 获取关联对象使用objc_removeAssociatedObjects 移除关联对象使用

第二种:使用newtonsoft.json来设置格式化的方式(推荐使用)

用法

一般我用在category里,合理使用它能让category发挥更大的作用。

  • UIViewcategory

.h文件

#import <UIKit/UIKit.h>@interface UIView typedef void (^GestureActionBlock)(UIGestureRecognizer *ges);/** 单点击手势 */- tapGesture:(GestureActionBlock)block;/** 长按手势 */- longPressGestrue:(GestureActionBlock)block;@end

.m文件

#import "UIView+WT.h"#import <objc/runtime.h>@implementation UIView static char kActionHandlerTapBlockKey;static char kActionHandlerTapGestureKey;static char kActionHandlerLongPressBlockKey;static char kActionHandlerLongPressGestureKey;//单点击手势- tapGesture:(GestureActionBlock)block { self.userInteractionEnabled = YES; UITapGestureRecognizer *gesture = objc_getAssociatedObject(self, &kActionHandlerTapGestureKey); if  { gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleActionForTapGesture:)]; [self addGestureRecognizer:gesture]; objc_setAssociatedObject(self, &kActionHandlerTapGestureKey, gesture, OBJC_ASSOCIATION_RETAIN); } objc_setAssociatedObject(self, &kActionHandlerTapBlockKey, block, OBJC_ASSOCIATION_COPY);}- handleActionForTapGesture:(UITapGestureRecognizer *)gesture { if (gesture.state == UIGestureRecognizerStateRecognized) { GestureActionBlock block = objc_getAssociatedObject(self, &kActionHandlerTapBlockKey); if  { block; } }}//长按手势- longPressGestrue:(GestureActionBlock)block { self.userInteractionEnabled = YES; UILongPressGestureRecognizer *gesture = objc_getAssociatedObject(self, &kActionHandlerLongPressGestureKey); if  { gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleActionForLongPressGesture:)]; [self addGestureRecognizer:gesture]; objc_setAssociatedObject(self, &kActionHandlerLongPressGestureKey, gesture, OBJC_ASSOCIATION_RETAIN); } objc_setAssociatedObject(self, &kActionHandlerLongPressBlockKey, block, OBJC_ASSOCIATION_COPY);}- handleActionForLongPressGesture:(UITapGestureRecognizer *)gesture { if (gesture.state == UIGestureRecognizerStateBegan) { GestureActionBlock block = objc_getAssociatedObject(self, &kActionHandlerLongPressBlockKey); if  { block; } }}@end

我解释下里面的一些关键字段,比如OBJC_ASSOCIATION_RETAIN这个字段实际上是个枚举来的

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) { OBJC_ASSOCIATION_ASSIGN = 0, /**< Specifies a weak reference to the associated object. */ OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. * The association is not made atomically. */ OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /**< Specifies that the associated object is copied. * The association is not made atomically. */ OBJC_ASSOCIATION_RETAIN = 01401, /**< Specifies a strong reference to the associated object. * The association is made atomically. */ OBJC_ASSOCIATION_COPY = 01403 /**< Specifies that the associated object is copied. * The association is made atomically. */};

用法跟@property中的strong 、weak、copy 、assign 、retain等声明属性的修饰符一样,我上面用到了block就对应OBJC_ASSOCIATION_COPY,而UITapGestureRecognizerUILongPressGestureRecognizer则对应OBJC_ASSOCIATION_RETAIN进行修饰。当然实际上我的UIViewcategory不止这些,可以参考我开发项目总结的一套库WTSDK可能有些地方描述得不是很好,或者描述错误了,希望你们能给我留言,thank!

本文由俄罗斯贵宾会发布于编程,转载请注明出处:iOS Runtime特性之关联对象

您可能还会对下面的文章感兴趣: