iOS底层学习-day-7
前言-OC语法篇
我是一名iOS开发者, iOS底层 菜鸟的进阶之路30天。
问题
Category能否添加成员变量?如果可以,如何给Category添加成员变量?
- 不能直接给Category添加成员变量,但是可以间接实现Category有成员变量的效果
关联对象
- 方法一
- 分类中只会实现成员变量的set和get方法声明,因为struct category_t中没有可以存放属性的地方
- 关联对象的第一种做法问题:
- 字典不会释放,内存会泄漏
- 线程不安全
#define MJKey [NSString stringWithFormat:@"%p", self]
@implementation MJPerson (Test)
NSMutableDictionary *names_;
NSMutableDictionary *weights_;
+ (void)load {
weights_ = [NSMutableDictionary dictionary];
names_ = [NSMutableDictionary dictionary];
}
- (void)setName:(NSString *)name {
// NSString *key = [NSString stringWithFormat:@"%p", self];
names_[MJKey] = name;
}
- (NSString *)name {
// NSString *key = [NSString stringWithFormat:@"%p", self];
return names_[MJKey];
}
- 方法二 常用方法
- (void)setName:(NSString *)name {//@selector(name) 是一个指向结构体的指针
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
// _cmd 是当前方法的名字
// (id)self (SEL)_cmd每个get函数都有这两个隐式参数
// 如果setName方法中写_cmd,就是@selector(setName)
- (NSString *)name:(id)self _cmd:(SEL)_cmd {// 隐式参数
// _cmd == @selector(name)
// objc_getAssociatedObject(self, @selector(name));
return objc_getAssociatedObject(self, _cmd);
}
实现关联对象 技术的核心对象有
- AssociationsManager
- AssociationsHashMap
- ObjectAssociationMap
- ObjcAssociation
- objc_removeAssociatedObjects
{
MJPerson *temp = [[MJPerson alloc] init];
objc_setAssociatedObject(person, @"temp", temp, OBJC_ASSOCIATION_ASSIGN);
}
NSLog(@"%@", objc_getAssociatedObject(person, @"temp"));
- ps:如果要移除就直接设置空,person.name = nil;
- 或者:移除所以关联对象objc_removeAssociatedObjects(id object)
- objc_setAssociatedObject是没用weak引用这种效果的,需要自己释放,注意,不然会出现访问空地址,因为person已经被销毁
block
- Block底层是一个结构体
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;//void *FuncPtr;这个就是将来代码块的地址
};
- block本质上也是一个OC对象,它内部也有个isa指针
- block是封装了 函数调用(就是里面的代码块) 以及 函数调用环境(就是外面带有东西) 的OC对象