OC category4

95 阅读3分钟

「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战」。

OC基础 - 类添加成员变量
属性 = ivar + setter(声明,实现) + getter(声明,实现)
类扩展
属性= 没有成员变量 + setter(声明) + getter(声明)

因为类扩展没有成员变量,所以属性也用不到,因为不能对其进行setter以及getter方法,所以想办法给类扩展属性增加一个成员变量

方法1 (肯定不可行啦)

增加一个全局变量

#import "MJPerson+Test.h"

int ages_;

@implementation MJPerson (Test)
- (void)setAge:(int)age
{
    ages_ = age;
}
- (int)age
{
    return ages_;
}

@end

这个时候存在的问题如下所示

    MJPerson * p1 = [[MJPerson alloc]init];
        p1.name = @"James";
        p1.age = 23;
       
        
        MJPerson * p2 = [[MJPerson alloc]init];
        p2.name = @"Durant";
        p2.age = 7;
        
        
        MJPerson * p3 = [[MJPerson alloc]init];
        p2.name = @"Harden";
        p2.age = 13;
        NSLog(@"p2.name = %@,age = %d",p2.name,p2.age);
        NSLog(@"p1.name = %@,age = %d",p1.name,p1.age);
        NSLog(@"p3.name = %@,age = %d",p3.name,p3.age);

打印输出

2022-02-21 11:03:53.319031+0800 CategoryAssociate[40891:1338125] p2.name = Harden,age = 13
2022-02-21 11:03:53.319529+0800 CategoryAssociate[40891:1338125] p1.name = James,age = 13
2022-02-21 11:03:53.319587+0800 CategoryAssociate[40891:1338125] p3.name = (null),age = 13

原因分析:后面传进来的age的值会将全局变量ages_进行覆盖,所以导致之前所有的值都是最后一个传进来的值

方法2(方法也会欠缺)

(NSMutableDictionary) 通过键值对,每一个person有对应的自己的age,一对一关系所以为字典
在load方法里给字典初始化,因为load方法只会被调用一次

+(void)load
{
    //在load里面给NSMutableDictionary *ages_;赋值,load只调用一次
    
    ages_ = [NSMutableDictionary new];
}

然后通过字典里的key取出value,这边用伪代码(思路)表示先,这样就可以暂时获取到所谓的成员变量,这个时候再写setter和getter方法

- (void)setAge:(int)age
{
    //通过字典里的key取出字典里的value
    //伪代码
     ages_[self] = @(age);
}
- (int)age
{
   return [ages_[self] intValue];
}

替换掉伪代码,则整个代码如下所示
主要是字典里的key一般都是NSString类型(用当前person类的内存地址做为key),所以self 替换成 NSString *ages = [NSString stringWithFormat:@"%p",self];
并将其设置为一个宏,因为多处会用到

#import "MJPerson+Test.h"
#define MJKey [NSString stringWithFormat:@"%p",self]


NSMutableDictionary *ages_;

@implementation MJPerson (Test)

+(void)load
{
    //在load里面给NSMutableDictionary *ages_;赋值,load只调用一次
    
    ages_ = [NSMutableDictionary new];
}

- (void)setAge:(int)age
{
    //通过字典里的key取出字典里的value
    //伪代码
   
    ages_[MJKey] = @(age);
}
- (int)age
{
    return [ages_[MJKey] intValue];
}

@end

调用

        MJPerson * p1 = [[MJPerson alloc]init];
        p1.name = @"James";
        p1.age = 23;
       
        
        MJPerson * p2 = [[MJPerson alloc]init];
        p2.name = @"Durant";
        p2.age = 7;
        
        

  /**
         struct MJPerson_IMPl{
             class isa;
             NSString *_name;
         }
         */

        MJPerson * p3 = [[MJPerson alloc]init];
        p3.name = @"Harden"; // @"Harden"是存储在person对象的内部 ,@"Harden" 是赋值给_name的  
        p3.age = 13; 13不是存在于person内部,13是存在于全局的字典对象里面,但是对外界来讲是没有什么区别的

        NSLog(@"p3.name = %@,age = %d",p3.name,p3.age);
        NSLog(@"p2.name = %@,age = %d",p2.name,p2.age);
        NSLog(@"p1.name = %@,age = %d",p1.name,p1.age);
  

打印结果

2022-02-21 11:29:18.562053+0800 CategoryAssociate[41418:1361256] p3.name = Harden,age = 13
2022-02-21 11:29:18.562517+0800 CategoryAssociate[41418:1361256] p2.name = Durant,age = 7
2022-02-21 11:29:18.562579+0800 CategoryAssociate[41418:1361256] p1.name = James,age = 23

方法二总结:问题:1.线程安全(每一个person的set方法都会访问全局的字典,不同person对象,在不同线程同时访问这个字典就会造成线程安全问题),
2.内存泄漏(因为是全局变量,而却一直在内存中)
3.如果增加多个属性,那么就会存在多个这样的字典,就要增加其对应的setter和getter方法