美文网首页iOS开发攻城狮的集散地
iOS autoreleasepool 动态添加属性

iOS autoreleasepool 动态添加属性

作者: 烟雨痕 | 来源:发表于2018-06-04 20:58 被阅读6次
内存管理模型基于持有关系的概念。如果一个对象正处于被持有状态,
那它占用的内存就不会被回收。而这种持有关系计数被正式成为引用计数。
ARC是一种编译器特性,它评估了对象在代码中的生命周期,并在编译是自动注入适合的内存管理调用。
参考:https://zhuanlan.zhihu.com/p/37463055

一、创建过多线程不会直接导致watchdog强杀,但过多线程可能导致主线程得不到及时处理,而因为
其他原因被kill。
二、CPU长时间过载并不会导致强杀,但系统会生成一个report来警告开发者:‘this is not a crash’的
crash日志。
三、避免创建过多线程。

一、autoreleasepool

在一些特定情况下,需要创建自己的autoreleasepool块
1.当有一个创建了很多临时对象的循环时:
在循环中使用autoreleasepool块可以为每个迭代释放内存,虽然迭代前后最终的内存使用相同,但是应用的最大内存需求可以大大降低。

for (NSDictionary * item in items) {
        @autoreleasepool {//确保在每次循环迭代完成后,清理内存从而导致更少的内存需求
                   Sku * sku = [Sku mj_objectWithKeyValues:item];
                    if ([item objectForKey:@"deleted_at"] && ![[item objectForKey:@"deleted_at"] isKindOfClass:[NSNull class]] && [[item objectForKey:@"deleted_at"] length]) {
                        [delSku addObject:sku];
                    }
                    else {
                        [addSku addObject:sku];
                    }
                    if (sku.productId && ![itemIds containsObject:[NSNumber numberWithInteger:sku.productId]]) {
                        [itemIds addObject:[NSNumber numberWithInteger:sku.productId]];
                    }
                }
            }

2.当创建一个线程时:

    每个线程都将有它自己的autoreleasepool块栈。主线程用自己的autoreleasepool启动。对于任何
自定义的线程,必须创建自己的autoreleasepool。

二、使用RunTime动态添加属性

参考文章:https://www.jianshu.com/p/0f9b990e8b0a

.h文件
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#import "UserName.h"

@interface NSObject (Clothing)

@property (nonatomic, copy) NSString *clothingName;

@property (nonatomic, copy) NSString *titleName;

//根据不同状态设置UserName
- (void)gm_setUserName:(UserName *)userName forState:(UIControlState)state;
//根据不同状态值获取UserName
- (UserName *)userNameForState:(UIControlState)state;

@end
.m文件
#import "NSObject+Clothing.h"
#import <objc/runtime.h>

static NSString *_clothingName;

static const void *TitleNameKey = &TitleNameKey;

static char TitleNameCharKey;

static char NameKeyNormal;//默认
static char NameKeySelected;//选中
static char NameKeyDisabled;//禁止
static const char *gm_NameKeyForState(UIControlState state) {
    switch (state) {
        case UIControlStateNormal:
            return  &NameKeyNormal;
        case UIControlStateSelected:
            return  &NameKeySelected;
        case UIControlStateDisabled:
            return  &NameKeyDisabled;
        default:
            return &NameKeyNormal;
    }
}

@implementation NSObject (Clothing)
//一、通过使用静态全局变量给分类添加属性
//但是这样_titleName静态全局变量与类并没有关联,无论对象创建与销毁,只要程序在运行_titleName变量就存在,并不是真正意义上的属性
- (void)setClothingName:(NSString *)clothingName {
    _clothingName = clothingName;
}
- (NSString *)clothingName {

    return _clothingName;
}

//方法二:使用RunTime动态添加属性

/**
 总结:1.一个实例对象就对应一个ObjectAssociationMap,而ObjectAssociationMap中存储多个此实例对象的关联对象的key以及ObjectAssociation,为ObjcAssionation中存储着关联对象的value和policy策略
     2.关联对象并不是放在原来的对象里面,而是自己维护了一个全局的map用来存放每一个对象以及对应关联属性表格。
     3.如果设置关联对象为nil, 就相当于是移除关联对象
 */
- (void)setTitleName:(NSString *)titleName {
    //动态添加属性
    //第一种
    objc_setAssociatedObject(self, TitleNameKey, titleName, OBJC_ASSOCIATION_COPY_NONATOMIC);
    //第二种
    objc_setAssociatedObject(self, @selector(setTitleName:), titleName, OBJC_ASSOCIATION_COPY_NONATOMIC);
    //第三种
    objc_setAssociatedObject(self, &TitleNameCharKey, titleName, OBJC_ASSOCIATION_COPY_NONATOMIC);
    
}

- (NSString *)titleName {
    //获取属性
    return objc_getAssociatedObject(self, TitleNameKey);
}


- (UserName *)userNameForState:(UIControlState)state {
    //获取属性
    return (UserName *)objc_getAssociatedObject(self, gm_NameKeyForState(state));
}

- (void)gm_setUserName:(UserName *)userName forState:(UIControlState)state {
    //设置属性
    objc_setAssociatedObject(self, gm_NameKeyForState(state), userName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)removeAssocatedObjects {
    //移除所有关联对象
    objc_removeAssociatedObjects(self);
}

@end


相关文章

  • iOS autoreleasepool 动态添加属性

    一、autoreleasepool 在一些特定情况下,需要创建自己的autoreleasepool块1.当有一个创...

  • iOS runtime 动态添加属性,方法,方法交换案例

    iOS runtime 动态添加属性,方法,方法交换案例 动态添加属性 我之前写过分类的文章,说过,分类不能添加成...

  • iOS动态添加属性

    如何在不破坏原有类封装下添加属性( 动态添加property ) 当我们想给系统类或者自定义基类添加某个属性(简称...

  • 二十一:Python之动态添加属性方法

    一:动态添加属性方法 动态添加属性:类属性,成员属性 动态添加方法:成员方法,类方法,静态方法 动态添加对象方法需...

  • Add CGFloat property to Category

    给扩展类添加CGFloat类型的属性 IOS中可以使用运行时动态给类添加属性,对象类型的属性添加方法大家都知道 但...

  • 动态添加属性

    动态添加属性:什么时候需要动态添加属性? 开发场景:给系统的类添加属性的时候,可以使用runtime动态添加属性方...

  • runtime常见问题

    1 . iOS runtime 运行时,动态添加属性方法首先, 要明白为什么要动态给类添加方法? 如果一个类方法很...

  • iOS runtime ~ 动态添加属性

    //联系人:石虎QQ:1224614774昵称:嗡嘛呢叭咪哄 一、概念 1.runtime:动态添加属性:什么时...

  • ios OC动态添加属性

  • iOS - Runtime 动态添加属性

    我们在开发中常常使用类目Category为一些已有的类扩展功能。虽然继承也能够为已有类增加新的方法,而且相比类目更...

网友评论

    本文标题:iOS autoreleasepool 动态添加属性

    本文链接:https://www.haomeiwen.com/subject/vazysftx.html