OutMan——集合对象的内存管理、copy的介绍及使用

来源:互联网 发布:java map 迭代器 编辑:程序博客网 时间:2024/05/17 06:09

集合对象的内存管理

一、集合对象的内存管理代码分析
(1)分析1:
这里写图片描述
-分析得出结论:
1. 当对象被添加到数组中的时候,对象的引用计数器加1
2. 当数组被销毁的时候,数组会向它其中的元素发送一条release消息

(2)分析2:
这里写图片描述
-分析得出结论:
1. 当对象从数组中移除的时候,对象的引用计数器减1

二、集合内存管理总结
(1)官方内存管理原则:
1. 当调用alloc、new、copy和mutableCopy方法产生一个新对象的时候,就必须在最后调用一次release或者autorelease方法
2. 当调用retain方法让对象的引用计数器加1,就必须在最后调用一次release或者autorelease方法
(2)集合的内存管理细节:
1. 把一个对象添加到集合中的时候,这个对象会做一次retain操作,对象的计数器会加1
2. 当一个集合被销毁的时候,这个集合里面的所有的对象都会做一次release操作,计数器会减1
3. 当一个对象从集合中移除的时候,这个对象会做一次release操作,计数器会减1
(3)普遍规律:
1. 如果方法名是add \ insert开头,那么被添加的对象的计数器会加1
2. 如果方法名是remove \ delete开头,那么被删除的对象的计数器会减1
(4)特别注意:当一个集合被销毁时,它里面存储的对象不一定被销毁,仅仅是做一次release操作

copy的介绍与使用

一、copy概念及入门
(1)什么是copy
        copy的字面意思是“复制”、“拷贝”,是一个产生副本的过程,常见的复制是一个源文件通过复制,产生一个副本文件
(2)对象copy的概念
        对象拷贝的目的:要使用某个对象的数据,但是在修改对象的时候不影响原来对象的内容

二、copy的特点
1. 修改源文件的内容,不会影响副本文件;修改副本文件的内容,不会影响源文件
2. OC中的copy,就指的是对象的拷贝,作用是利用一个源对象产生一个副本对象
3. 修改源对象的属性和行为,不会影响副本对象;修改副本对象的属性和行为,不会影响源对象

三、如何使用copy的功能
        一个对象可以调用copy方法或mutableCopy方法来产生一个副本对象
1. copy:创建的是不可变副本(如:NSString、NSArray、NSDictionary)
2. mutableCopy:创建的是可变副本(如:NSMutableString、NSMutableArray、NSMutableDictionary)

四、使用copy功能的前提
1. copy:需要遵守NSCopying协议,实现copyWithZone:方法

@protocol NSCopying- (id)copyWithZone:(NSZone *)zone;@end
  1. mutableCopy:需要遵守NSMutableCopying协议,实现mutableCopyWithZone:方法
@protocol NSMutableCopying- (id)mutableCopyWithZone:(NSZone *)zone;@end

五、copy和mutableCopy功能的代码分析
这里写图片描述
这里写图片描述
分析得出结论:
1. copy:创建的是不可变副本
2. mutableCopy:创建的是可变副本

六、深复制和浅复制
1. copy就是浅复制,因为没有产生新的对象
2. mutableCopy就是深复制,会在内存中重新分配一块内存空间
3. 有没有产生新的对象也是判断深浅复制的标准

七、copy与内存管理的代码分析
(1)分析一:
这里写图片描述
分析得出结论:
1. 由于地址相同,所以可以得出结论:不可变的对象进行copy以后,没有重新分配内存空间
2. 这是浅拷贝,只拷贝了地址,并没有真正的分配新的内存空间(源对象的引用计数器加1,副本对象指向源对象,引用计数器也增加了)
这里写图片描述

(2)分析二:
这里写图片描述
分析得出结论:
1. 由于地址不相同,所以可以得出结论:不可变的对象进行mutableCopy以后,重新分配一个新内存空间
2. 这是深拷贝,开辟了一个新的空间存储副本对象(副本对象的引用计数器为1)
这里写图片描述

八、copy与内存管理的总结:
(1)深复制(深拷贝、内容复制、deep copy)
1. 源对象和副本对象是不同的两个对象
2. 源对象的引用计数器不变,副本对象的引用计数器为1
3. 本质:产生了新的对象
(2)浅复制(浅拷贝、指针拷贝、shallow copy)
1. 源对象和副本对象是同一个对象
2. 源对象(副本对象)引用计数器加1,相当于做了一次retain操作
3. 本质:没有产生新的对象

九、@property中的copy关键字

@property(nonatomic, copy)NSString *name;// set方法的展开形式- (void)setName:(NSString *)name{    if (name != _name)    {        [_name release];        _name = [name copy];    }}

十、@property内存管理策略选择
(1)非ARC(MRC)
1. copy:只用于NSString \ block
2. retain:除NSString \ block以外的OC对象
3. assign:基本数据类型,枚举、结构体(非OC对象),当两个对象循环引用的时候,一端用retain,另一端使用assign
(2)ARC
1. copy:只用于NSString \ block
2. strong:除NSString \ block以外的OC对象
3. weak:当两个对象循环引用的时候,一端用strong,另一端使用weak
4. assign:基本数据类型,枚举、结构体(非OC对象)

十一、为自定义类实现copy操作
(1)自定义对象copy步骤
1. 新建Person类
2. 为Person类实现copy操作
<1> 让Person类遵守NSCopying协议
<2> 实现copyWithZone:方法,在该法中返回一个对象的副本即可
<3> 在copyWithZone方法中,创建一个新的对象,并设置该对象的数据与现有对象一致,并返回该对象
3. 创建Person对象,调用copy方法,查看地址
(2)细节介绍
1. 调用copy其实就是调用copyWithZone方法,所以实现copyWithZone方法(查看NSObject协议中的copy方法介绍)
2. copyWithZone方法返回值类型是id类型,需要返回一个对象的副本
3. 关于copyWithZone的参数zone问题
<1> zone:表示空间,分配对象是需要内存的,如果指定了zone,就可以指定新建对象对应的内存空间,但是:zone是一个非常古老的技术,为了避免在堆中出现内存碎片而使用的,在今天的开发中,zone几乎可以忽略
<2>查看NSObject协议中的copyWithZone:方法介绍(zone参数可以被忽略,是历史原因)
4. 如果对象没有可变 / 不可变的版本区别,只要实现copyWithZone方法即可

十二、为自定义类实现copy操作的代码实现
(1)Person类的设计
                                                                     Person.h文件

#import <Foundation/Foundation.h>@interface Person : NSObject<NSCopying>@property(nonatomic, assign)int age;   // 年龄@property(nonatomic, assign)float weight;   // 体重@end

                                                                     Person.m文件

@implementation Person// 实现copyWithZone:(NSZone *)zone方法- (id)copyWithZone:(NSZone *)zone{    Person *p = [[Person alloc] init];    p.weight = self.weight;    p.age = self.age;    return p;}@end

(2)main.m文件
这里写图片描述
注意:
1. 自定义对象的拷贝都是深拷贝

十三、为Person类实现mutableCopy操作
1. 遵守NSMutableCopying协议
2. 实现协议中需要实现的方法

// 实现mutableCopyWithZone:(NSZone *)zone- (id)mutableCopyWithZone:(NSZone *)zone{    Person *p = [[Person alloc] init];    p.weight = self.weight;    p.age = self.age;    return p;}

十四、为Person类实现mutableCopy操作的代码实现
(1)Person类的设计
                                                                     Person.h文件

#import <Foundation/Foundation.h>@interface Person : NSObject<NSMutableCopying>@property(nonatomic, assign)int age;   // 年龄@property(nonatomic, assign)float weight;   // 体重@end

                                                                     Person.m文件

#import "Person.h"@implementation Person// 实现mutableCopyWithZone:(NSZone *)zone- (id)mutableCopyWithZone:(NSZone *)zone{    Person *p = [[Person alloc] init];    p.weight = self.weight;    p.age = self.age;    return p;}@end

(2)main.m文件
这里写图片描述


                                        —— 如果您有不同的见解,请随时指出,期待与您的交流!——


0 0
原创粉丝点击