IOS在分类中实现添加属性的效果-非关联版

在分类中添加属性@property (nonatomic) id newProperty;只会生成set和get方法,但不会生成成员变量的;若想实现在分类中添加属性@property (nonatomic) id newProperty;就像在原类中添加属性一样的效果,可以通过运行时的关联引用来实现,但本文介绍一种不用关联引用来实现的方案,如下:

用NSObject的分类来进行演示;

一、 在NSObject(BYExtension)分类中给相应的属性添加@property,以方便打点调用:

如:

@property (nonatomic) id newProperty;

二、在分类文件中方法外面添加NSMutableDictionary *类型的静态态变量,用来存放所有实例的属性-值字典:

如:

static NSMutableDictionary * _warehouseProperty;

这里之所以要用可变字典,是为了方便存取,如果换成其它的容器,实现起来相当麻烦,所以要用字可变字典;

三、实现get和set方法:

如:

//给newProperty属性赋值
-(void)setNewProperty:(id)newProperty
{
    // 确保_warehouseProperty可变字典存在且只创建一次
    if (_warehouseProperty == nil) {
        _warehouseProperty = [[NSMutableDictionary alloc] init];
    }
    
    // 为了实现分类中能添加多个属性,需要为每个实例维护一份存属性值的可变字典
    if (_warehouseProperty[self] == nil) {
        _warehouseProperty[self] = [[NSMutableDictionary alloc] init];
    }
    
    //nil不能存到字典中
    if (newProperty != nil) {
        //每个实例都有一个可变字典,用来存储不同属性的值,用属性名作键,属性值作值
        _warehouseProperty[self][@"newProperty"] = newProperty;
    }
    
}


//返回属性的值
-(id)newProperty
{
    return _warehouseProperty[self][@"newProperty"];
}

四、实现NSCopying协议:

因为NSDictionary要求,作为Key的对象必须得遵守NSCopying协议,所以要该类实现NSCopying协议;
如:

接口文件:

@interface NSObject(BYExtension) <NSCopying>    //因为要把该类的实例用作字典的键,所以需要实现NSCopying协议;
- (id)copyWithZone:(nullable NSZone *)zone;

实现文件:

//NSCopying协议的实现;因为要把该类的实例用作字典的键,所以需要实现NSCopying协议;
- (id)copyWithZone:(nullable NSZone *)zone
{
    return self;
}

完成之后,整个分类的效果如下:

NSObject(BYExtension).h文件:

#import <Foundation/Foundation.h>

@interface NSObject(BYExtension) <NSCopying>    //因为要把该类的实例用作字典的键,所以需要实现NSCopying协议;

@property (nonatomic) id newProperty;

- (id)copyWithZone:(nullable NSZone *)zone;

@end

NSObject(BYExtension).m文件:

#import "NSObject(BYExtension).h"


static NSMutableDictionary * _warehouseProperty;    //用类存储属性值的字典

@implementation NSObject(BYExtension)


//NSCopying协议的实现;因为要把该类的实例用作字典的键,所以需要实现NSCopying协议;
- (id)copyWithZone:(nullable NSZone *)zone
{
    return self;
}


//给newProperty属性赋值
-(void)setNewProperty:(id)newProperty
{
    // 确保_warehouseProperty可变字典存在且只创建一次
    if (_warehouseProperty == nil) {
        _warehouseProperty = [[NSMutableDictionary alloc] init];
    }
    
    // 为了实现分类中能添加多个属性,需要为每个实例维护一份存属性值的可变字典
    if (_warehouseProperty[self] == nil) {
        _warehouseProperty[self] = [[NSMutableDictionary alloc] init];
    }
    
    //nil不能存到字典中
    if (newProperty != nil) {
        //每个实例都有一个可变字典,用来存储不同属性的值,用属性名作键,属性值作值
        _warehouseProperty[self][@"newProperty"] = newProperty;
    }
    
}


//返回属性的值
-(id)newProperty
{
    return _warehouseProperty[self][@"newProperty"];
}


@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.项目经验 2.基础问题 3.指南认识 4.解决思路 ios开发三大块: 1.Oc基础 2.CocoaTouch...
    阳光的大男孩儿阅读 10,468评论 0 13
  • 这世界上真的没有冷男,只是人家暖的不是自己。
    不如怀念9527阅读 936评论 0 0
  • 外面,弟弟在叫我,我跑了出去。弟弟正站在走廊上,指着天空叫道:“姐,看!大雁!” 我抬起头向北方的天空看去,只见两...
    佘玺阅读 1,722评论 0 2
  • 这个季节没有浪漫的情话了 只有冷风孤独的吹 冬天也终于来了你也终于不知去向了 只有略带玩笑的承诺了 这里又下雪了四...
    南方同学阅读 2,642评论 0 0