copy与mutableCopy的内存管理剖析
title: copy与mutableCopy的内存管理剖析
date: 2016-04-24 16:50:04
tags: copy
copy与mutableCopy相关的内存管理
不知道为什么一说这个,很多人都拿NSString和NSMutableString做测试,我想最直接的是因为常用又实现了copy和mutableCopy的代理,但是NSString类的其实比较特殊,不应该拿NSString来测试,所以本文拿实现代理的NSURLRequest来做测试。
immutableObject:
非集合的
NSURL *url = [[NSURL alloc] initWithString:@"ceshi"];NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url];NSLog(@"urlReqeust:%@, urlRequestRec:%ld", urlRequest, [urlRequest retainCount]); //log: urlReqeust: { URL: ceshi }, urlRequestRec:1
NSURLRequest *urlRequest1 = [urlRequest copy];
NSLog(@"urlRequest1:%@, urlRequest1:%ld", urlRequest1, [urlRequest1 retainCount]);
// log: urlRequest1: { URL: ceshi }, urlRequest1:2
总结:immutableObject做copy时,做的是浅copy,也就是说只是所指向的对象的内存计数器增加了1,所以如果urlRequest1重新赋值时,需要做下release把之前所指的对象的内存计数器减1,否则就会有内存泄露。如下:
[urlRequest1 release], urlRequest1 = nil;// 此时urlRequest所指对象计数器为1,urlRequest1为nilurlRequest1 = [NSURLRequest requestWithURL:[NSURL URLWithString:@"ceshi2"]];// 此时urlRequest1指向新的对象,指向的对象的计数器为1
集合的
NSArray *array = @[@[@"a", @"b"], @[@"c", @"d"]];NSArray *copyArray = [array copy];NSMutableArray *mCopyArray = [array mutableCopy];// log: =====array:0x7fb2a8f0d2b0,arrayRec:2, =====copyArray:0x7fb2a8f0d2b0,copyArrayRec:2, ======mCopyArry:0x7fb2a8e10ef0, mCopyArrayRec:1
// 有bug,必须要做copyArray的release
copyArray = @[@"a",@"d"];
NSLog(@"array:%@,copyArr:%@,mCopyArray:%@", array, copyArray, mCopyArray);
// log: =====array:0x7fb2a8f0d2b0,arrayRec:2, =====copyArray:0x7fb2a8f1b980,copyArrayRec:1, ======mCopyArry:0x7fb2a8e10ef0, mCopyArrayRec:1
与immutable的非集合一样,copy将直接增加指针指向对象的引用计数器(集合的话:各元素的指针计数器都增加了1)。所以在copyArray更改前,必须要做release,否则会有内存泄漏
mutableObject
非集合的
NSURL *url = [[NSURL alloc] initWithString:@"ceshi"];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url];
NSLog(@"urlReqeust:%@, urlRequestRec:%ld\r", urlRequest, [urlRequest retainCount]);
// log: urlReqeust:<NSURLRequest: 0x7f98dac07e00> { URL: ceshi }, urlRequestRec:1NSMutableURLRequest *mutableRequest = [urlRequest mutableCopy];
NSLog(@"mutableRequest:%@, mutableRequest:%ld", mutableRequest, [mutableRequest retainCount]);
// log: mutableRequest:<NSMutableURLRequest: 0x7f98daf07390> { URL: ceshi }, mutableRequest:1NSMutableURLRequest *mutableRequest1 = [mutableRequest mutableCopy];
NSLog(@"mutableRequest1:%@, mutableRequest1:%ld", mutableRequest1, [mutableRequest1 retainCount]);
// log: mutableRequest1:<NSMutableURLRequest: 0x7f98dac674f0> { URL: ceshi }, mutableRequest1:1
集合的
NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];NSArray *copyArray = [array copy];NSMutableArray *mCopyArray = [array mutableCopy];// log: =====array:0x7fbbd3d0d730,arrayRec:1, =====copyArray:0x7fbbd3d19610,copyArrayRec:1, ======mCopyArry:0x7fbbd3d18ad0, mCopyArrayRec:1
总结:mutableObject的复制是深复制,直接创建一个新的内存地址来复制其内容(在集合中把各个元素的内容都赋值了一遍)。 与之前的被复制项无任何关系。
汇总:
- [immutableObject copy] // 浅复制
- [immutableObject mutableCopy] //深复制
- [mutableObject copy] //深复制
- [mutableObject mutableCopy] //深复制
特殊的NSString
NSString *str1 = @"abc";NSString *str2 = @"abc";NSString *str3 = [[NSString alloc] initWithString:@"abc"];NSString *str4 = [str1 copy];NSString *str5 = [[NSString alloc] initWithString:@"abc"];NSString *str6 = [str1 mutableCopy];
//输出内存中的地址
NSLog(@"str1: %p", str1);
NSLog(@"str2: %p", str2);
NSLog(@"str3: %p", str3);
NSLog(@"str4: %p", str4);
NSLog(@"str5: %p", str5);
NSLog(@"str6: %p", str6);
猜下结果:
2016-04-24 22:41:50.629 TestCopy[2094:229125] str1: 0x1081af070
2016-04-24 22:41:50.630 TestCopy[2094:229125] str2: 0x1081af070
2016-04-24 22:41:50.630 TestCopy[2094:229125] str3: 0x1081af070
2016-04-24 22:41:50.630 TestCopy[2094:229125] str4: 0x1081af070
2016-04-24 22:41:50.630 TestCopy[2094:229125] str5: 0x1081af070
2016-04-24 22:41:50.631 TestCopy[2094:229125] str6: 0x7fb1d3f0ce70
我的理解:
NSString在程序中使用非常大,所以在immutable的copy和mutableCopy的原理下,为了系统性能的考虑,增加了只要是NSString存在,则直接把字符串地址付给使用者即可。如果此时str2=@"abdt"了,则直接拿生成的abdt的地址赋值给str2即可。
NSMutableString与immutableObj类似
NSMutableString *str1 = [NSMutableString stringWithFormat:@"abc"];NSMutableString *str2 = [[NSMutableString alloc] initWithString:@"abc"];NSMutableString *str3 = [str1 copy];NSMutableString *str4 = [str1 mutableCopy];
//输出内存中的地址
NSLog(@"str1: %p, reC:%ld", str1, [str1 retainCount]);
NSLog(@"str2: %p, reC:%ld", str2, [str2 retainCount]);
NSLog(@"str3: %p", str3);
NSLog(@"str4: %p", str4);
log:
2016-04-24 22:58:42.319 TestCopy[2164:240308] str1: 0x7fa7ebca0c50, reC:1
2016-04-24 22:58:42.319 TestCopy[2164:240308] str2: 0x7fa7ebca8560, reC:1
2016-04-24 22:58:42.319 TestCopy[2164:240308] str3: 0xa000000006362613
2016-04-24 22:58:42.320 TestCopy[2164:240308] str4: 0x7fa7ebca7ed0
最后看2段代码:
//UserEntity.h@interface UserEntity : NSObject @property(strong, nonatomic) NSString *name;@endUserEntity *userEntity = [UserEntity new];//创建mutable类型的字符串NSMutableString *showName = [[NSMutableString alloc] initWithString:@"tutuge"];//先保存“tutuge”字符串到userEntity的nameuserEntity.name = showName;//修改showName[showName appendString:@" blog"];//输出userEntity的name属性NSLog(@"Name: %@", userEntity.name);
输出为:tutuge blog
如果更改为:@interface UserEntity : NSObject
@property(copy, nonatomic) NSString *name;
@end
则输出为: tutuge
copy与mutableCopy的内存管理剖析相关推荐
- Linux下ion内存,ION内存管理剖析.doc
1.android之ION内存管理器(1)-- 简介 为什么需要ION 2011年末[2],LWN审查了android kernel patch[3],以期望将这些patch合并到kernel主线中. ...
- Linux内存管理剖析
现在的服务器大部分都是运行在Linux上面的,所以作为一个程序员有必要简单地了解一下系统是如何运行的. 对于内存部分需要知道: 地址映射 内存管理的方式 缺页异常 先来看一些基本的知识,在进程看来,内 ...
- 内存管理-定时器循环、内存布局、tagged pointer、weak指针、copy、自动释放池
先上代码,我们平时用的定时器,cadisplaylink.nstimer,CADisplayLink.NSTimer会对target产生强引用,如果target又对它们产生强引用,那么就会引发循环引用 ...
- iPhone/Mac Objective-C内存管理教程和原理剖析
版权声明 此文版权归作者Vince Yuan (vince.yuan#gmail.com)所有.欢迎非营利性转载,转载时必须包含原始链接http://vinceyuan.cnblogs.com/,且必 ...
- MySQL深潜|剖析Performance Schema内存管理
简介: 本文主要是通过对PFS引擎的内存管理源码的阅读,解读PFS内存分配及释放原理,深入剖析其中存在的一些问题,以及一些改进思路. 一 引言 MySQL Performance schema(PF ...
- MYSQL深潜 - 剖析Performance Schema内存管理
简介: 本文主要是通过对PFS引擎的内存管理的源码的阅读,解读PFS内存分配及释放原理,深入剖析其中存在的一些问题,以及一些改进思路.本文源代码分析基于Mysql-8.0.24版本. 作者 | 之枢 ...
- assign/retain/copy各内存管理特性的差异
MRC下各内存管理特性 assign特性 当数据类型为int.float等原生类型时,可以使用assign,否则可能导致内存泄露.例如当使用malloc分配了一块内存,并把它的地址赋值给了指针a,后来 ...
- python内存管理和释放_《python解释器源码剖析》第17章--python的内存管理与垃圾回收...
17.0 序 内存管理,对于python这样的动态语言是至关重要的一部分,它在很大程度上决定了python的执行效率,因为在python的运行中会创建和销毁大量的对象,这些都设计内存的管理.同理pyt ...
- 《Linux内核剖析》(Yanlz+VR云游戏+Unity+SteamVR+云技术+5G+AI+Makefile+块设备驱动+字符设备驱动+数学协处理器+文件系统+内存管理+GDB+立钻哥哥+==)
<Linux内核剖析> <Linux内核剖析> 版本 作者 参与者 完成日期 备注 YanlzLinux_Kernel0.12_V01_1.0 严立钻 2020.02.06 # ...
最新文章
- windows中路径\和 linux中用/
- 手把手教你Tableau高级数据分析功能(附数据集)
- 精灵动画Animation对话框组成Idle动画的各精灵
- 使用Xmodem恢复交换机IOS
- windows 7 SDK和DDK下载地址
- 77. 组合016(回溯法)
- mybatis-启动源码分析
- STM32F1笔记(十)PWM
- python 字符串子串_Python字符串子字符串
- 毫米波雷达信号处理系统
- pl2303hxa串口线驱动_pl2303hx驱动下载
- EGM2008大地水准面模型在工程中的应用综述
- vscode配置和快捷键
- 女生29岁 ,想学前端,还来得及么?
- 《与韩荆州书》--李白经典求职信
- 内网渗透(五十二)之域控安全和跨域攻击-搭建和查看域信任关系
- 关于godot第三方功能增强版
- 豆芽的生长过程观察日记
- java opencv磨皮算法_美肤磨皮算法OpenCV3实现
- 阿里云服务器 远程桌面连接 卡顿
热门文章
- python debug工具_常用的 Python 调试工具,Python开发必读-乾颐堂
- Exception in thread main java.lang.NoSuchMethodError: scala.Predef$
- spring 扫描所有_SpringBoot和Spring到底有没有本质的不同?
- python作品_学习 Python 有些枯燥?那是你学错方法了,看这里
- Adobe Audition录制音频与剪辑
- python用辗转相除法求最大公约数
- 笔记-项目风险管理-转-从木桶效应谈对于安全管理的认识
- Python 办公自动化之一 Excel
- SqlServer 根据一个表数据更新另外一个表
- Winform中设置ZedGraph的曲线为折线、点折线、散点图