「这是我参与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方法