1.有漏洞的写法
- (void)rfClearPropertyValue {
//1.存储属性的个数
unsigned int propertyCount = 0;
// 2.通过运行时获取当前类的所有属性
objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);
// 3.遍历属性
for (int i = 0; i < propertyCount; i ++) {
objc_property_t property = properties[i];
NSString *propertyName = [NSString stringWithFormat:@"%s", property_getName(property)];
// 4.利用KVC 设置属性nil
[self setValue:nil forKey:propertyName];
}
// 释放指针
free(properties);
}
如果你的运气足够好,单例中所有的属性都是非基础类型,那么这么写是可以的,但是如果属性中有基础类型属性的时候(例如,int NSInterger),那么你会看到运行奔溃提示:could not set nil as the value for the key
2.升级版写法
- (void)clearPropertyValue {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
unsigned int propertyCount = 0;
// 2.通过运行时获取当前类的所有属性
objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);
// 3.遍历属性
for (int i = 0; i < propertyCount; i ++) {
objc_property_t property = properties[i];
NSString *propertyName = [NSString stringWithFormat:@"%s", property_getName(property)];
// 4.利用KVC 设置属性nil
@try {
[self setValue:nil forKey:propertyName];
} @catch (NSException *exception) {
[self setValue:@0 forKey:propertyName];
} @finally {
//
}
}
// 释放指针
free(properties);
});//此处使用在子线程中实现重置单例属性的写法,因为在block中使用此方法时有死锁的情况;
}
*注:本文内容来自于简述作者:@yannChee, 本文章只是在原作者写法上把开辟子线程的写法调整到方法内部,原文:<<利用Runtime清空单例属性>>