关闭

Foundation框架-08 集合对象的内存管理

229人阅读 评论(0) 收藏 举报
分类:

Foundation框架-08 集合对象的内存管理


1.操作集合对象对引用计数器的影响(非ARC模式下)

  • 官方内存管理原则

    • 当调用alloc、new、copy(mutableCopy)方法产生一个新的对象时,就必须在最后调用一次release或者autorelease
    • 当调用retain方法让对象的计数器+1,就必须在最后调用一次release或者autorelease
  • 集合对象的内存管理细节

    • 1> 当把一个对象添加到集合中时,这个对象会做了一次retain操作,计数器会+1
    • 当一个集合被销毁时,会对集合里面的所有对象做一次release操作,计数器会-1
    • 当一个对象从集合中移除时,这个对象会一次release操作,计数器会-1
  • 普遍规律

    • 如果方法名是add\insert开头,那么被添加的对象,计数器会+1
    • 如果方法名是remove\delete开头,那么被移除的对象,计数器-1

2.copy属性

  • 基本概念,copy的意思是拷贝,复制,即利用一个源对象产生一个副本对象

    • 修改源对象的属性和行为,不会影响副本对象
    • 修改副本对象的属性和行为,不会影响源对象
  • copy的使用

    • 一个对象可以调用copy或mutableCopy方法来创建一个副本对象
    • copy:创建的是不可变的副本(如NSString、NSArray、NSDictionary)
    • mutableCopy:创建的是可变副本(如NSMutableString、NSMutableArray、NSMutableDictionary)
  • 使用copy功能的前提

    • copy:需要遵守NSCopying协议,实现copyWithZone:方法,调用copy会自动实现copyWithZone:方法
    • mutableCopy:需要遵守NSMutableCopying协议,实现mutableCopyWithZone:方法
  • 浅复制和深复制

    • 浅复制(浅拷贝,指针拷贝,shallowcopy)
      • 源对象和副本对象是一个对象
      • 源对象(副本对象)引用计数器+1,相当于做了一次retain操作
      • 本质没有产生新的对象
    • 深复制(深拷贝,内容拷贝,deep copy)
      • 源对象和副本对象是不同的两个对象
      • 源对象引用计数器不变,副本对象计数器为1(因为是新产生的)
      • 本质是:产生了新的对象
  • 注意:只有源对象和副本对象都不可变时,才是浅复制,其它都是深复制

  • copy内存管理

    • 浅拷贝,原对象引用计数器+1,必须对原对象进行释放
    • 深拷贝,创建了新对象,必须对新对象释放
  • @property中的copy的作用

    • 防止外界修改内部的值
    • 防止访问对象已经释放
    • 若是用copy修饰block代表将block移到堆内存中,那么一旦在block中访问了某个对象,就会对该对象进行一次retain操作
    • 也可以使用Block_copy(myBlock);将block转移到堆中
    • 注意:
      • block默认存储在栈中,栈中的block对象访问了外界的对象,不会进行retain操作
      • block如果在堆中,一旦block中访问了外界的对象,会对外界的对象进行一次retain操作,防止block在使用对象之前,对象就已经释放,造成内存泄漏
      • 若是在block定义在一个类中,又在程序中访问了对象本身,那么为了避免内存泄漏想,需要将对象修饰为__block
  • 自定义对象实现copy操作

    • 让类遵守NSCopying或NSMutableCopying协议
    • 实现copyWithZone:方法,在该方法中返回一个对象的副本即可
    • 在copyWithZone方法中,创建一个新的对象,并设置该对象的数据与现有对象一致, 并返回该对象
  • 无父类实现
-(id)copyWithZone(NSZone *)zone{
CustomMode *custom = [[[self class]  copyWithZone:zone]  init];
Custom.a = [_a copyWithZone:zone];
Custom.c = _c;//不是对象的 直接赋值
Return custom;
}
  • 有父类实现
    • 不调用父类方法, 无法拷贝父类中继承的属性
    • 不重新调用父类copyWithZone,无法拷贝本来中的特有属性
-(id)copyWithZone(NSZone *)zone{

CustomModel *custom = [super copyWithZone:zone];
….
Return custom;
}

3. @property内存管理策略

  • 非ARC
    • copy : 只用于NSString\block
    • retain : 除NSString\block以外的OC对象
    • assign:基本数据类型、枚举、结构体(非OC对象),当2个对象相互引用,一端用retain,一端用assign
  • ARC
    • copy : 只用于NSString\block
    • strong :除NSString\block以外的OC对象
    • weak:当2个对象相互引用,一端用strong,一端用weak
    • assgin:基本数据类型、枚举、结构体(非OC对象)
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:36404次
    • 积分:1354
    • 等级:
    • 排名:千里之外
    • 原创:102篇
    • 转载:0篇
    • 译文:0篇
    • 评论:4条
    最新评论