iOS-内存管理就这么简单2
来源:互联网 发布:信用卡可以在淘宝套现 编辑:程序博客网 时间:2024/04/29 00:54
文明转转和评论是对自己的尊重也是对学者的鼓励,谢谢
iOS-内存管理就这么简单2
一.copy,mutableCopy的使用
NSArray *arr = [[NSArray alloc]initWithObjects:@"hello", nil]; NSArray *arr2 = [arr copy]; NSObject *obj = [[NSObject alloc]init]; NSLog(@"arr retainCout %ld",[arr retainCount]); NSLog(@"arr2 retainCout %ld",[arr2 retainCount]); NSLog(@"arr = %ld arr2 =%ld ",arr,arr2);
2015-01-17 23:26:04.977 MemoryManager[907:40309] arr retainCout 2
2015-01-17 23:26:04.977 MemoryManager[907:40309] arr2 retainCout 2
2015-01-17 23:26:04.977 MemoryManager[907:40309] arr = 140677793151936 arr2 =140677793151936
说明通过copy得到的是同一个对象,copy使堆内存对象的引用计数加一了。NSArray *arr = [[NSArray alloc]initWithObjects:@"hello", nil]; NSArray *arr2 = [arr mutableCopy]; NSObject *obj = [[NSObject alloc]init]; NSLog(@"arr retainCout %ld",[arr retainCount]); NSLog(@"arr2 retainCout %ld",[arr2 retainCount]); NSLog(@"arr = %ld arr2 =%ld ",arr,arr2);
2015-01-17 23:28:12.817 MemoryManager[927:41217] arr retainCout 1
2015-01-17 23:28:12.817 MemoryManager[927:41217] arr2 retainCout 1
2015-01-17 23:28:12.817 MemoryManager[927:41217] arr = 140285358613872 arr2 =140285358605248
说明mutableCopy使把arr中的内容完全的赋值一份并存在新分配的堆内存对象中,所以arr和arr2指向的是不同的内存对象;NSArray *arr = [[NSArray alloc]initWithObjects:@"hello", nil]; NSArray *arr2 = [arr mutableCopy]; if([arr2 respondsToSelector:@selector(addObject:)]){ NSLog(@"changed"); } NSObject *obj = [[NSObject alloc]init]; NSLog(@"arr retainCout %ld",[arr retainCount]); NSLog(@"arr2 retainCout %ld",[arr2 retainCount]); NSLog(@"arr = %ld arr2 =%ld ",arr,arr2);
运行结果:
2015-01-17 23:32:03.639 MemoryManager[950:42492] changed
2015-01-17 23:32:03.640 MemoryManager[950:42492] arr retainCout 1
2015-01-17 23:32:03.640 MemoryManager[950:42492] arr2 retainCout 1
2015-01-17 23:32:03.640 MemoryManager[950:42492] arr = 140367229411264 arr2 =140367229427648
NSMutableArray * arr2 = [[NSMutableArrayalloc]initWithArray:arr];
3.
NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:@"hello", nil]; NSMutableArray *arr2 = [arr mutableCopy]; if([arr2 respondsToSelector:@selector(addObject:)]){ NSLog(@"changed"); } NSObject *obj = [[NSObject alloc]init]; NSLog(@"arr retainCout %ld",[arr retainCount]); NSLog(@"arr2 retainCout %ld",[arr2 retainCount]); NSLog(@"arr = %ld arr2 =%ld ",arr,arr2);运行结果:
2015-01-17 23:38:24.378 MemoryManager[1034:44814] changed
2015-01-17 23:38:24.379 MemoryManager[1034:44814] arr retainCout 1
2015-01-17 23:38:24.379 MemoryManager[1034:44814] arr2 retainCout 1
2015-01-17 23:38:24.379 MemoryManager[1034:44814] arr = 140316907672672 arr2 =140316907807120
结果分析:可变数组mutableCopy还是可变数组,相当于NSMutableArray *arr2 = [[NSMutableArray alloc]initWithArray:arr];
arr和arr2还是指向不同堆中的对象,但它们的内容完全相同note:可变数组的mutableCopy之后还是可变的
5.
NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:@"hello", nil]; NSMutableArray *arr2 = [arr copy]; if([arr2 respondsToSelector:@selector(addObject:)]){ NSLog(@"changed"); } NSObject *obj = [[NSObject alloc]init]; NSLog(@"arr retainCout %ld",[arr retainCount]); NSLog(@"arr2 retainCout %ld",[arr2 retainCount]); NSLog(@"arr = %ld arr2 =%ld ",arr,arr2);
2015-01-17 23:41:36.505 MemoryManager[1058:46071] arr retainCout 1
2015-01-17 23:41:36.506 MemoryManager[1058:46071] arr2 retainCout 1
2015-01-17 23:41:36.506 MemoryManager[1058:46071] arr = 140719784280096 arr2 =140719784275712
说明可变的数组通过copy函数相当于:NSArray *arr2 = [[NSArray alloc]initWithArray:arr];
不同堆对象相同内容,这就是所谓的深拷贝和浅拷贝,但要注意拷贝之后的对象的属性性质的变化,其他的集合类和字符串也存在通过深拷贝和浅拷贝及对象性质的变化,所以在应用时要小心。note:可变的数组copy之后就成了不可变的。
二.循环引用和弱引用解决循环引用的内存泄漏
@interface CycleRetain : NSObject@property (nonatomic,retain)id retainObject;@end@implementation CycleRetain@end
CycleRetain *obj1 = [[CycleRetain alloc]init];//此时 obj1指向的堆对象的引用计数为1 CycleRetain *obj2 = [[CycleRetain alloc]init];//此时 obj2指向的堆对象的引用计数为1 NSLog(@"before "); NSLog(@"obj1 retainCount=%ld obj2 retainCount=%ld",obj1.retainCount,obj2.retainCount); obj1.retainObject = obj2; //因为retainObject是retain属性所以obj2指向的堆内存对象的引用计数要加1 ,此时为2 obj2.retainObject = obj1; //因为retainObject是retain属性所以obj1指向的堆内存对象的引用计数要加1 ,此时为2 NSLog(@"after"); NSLog(@"obj1 retainCount=%ld obj2 retainCount=%ld",obj1.retainCount,obj2.retainCount); //当改函数运行结束返回,此时obj1和obj2的声明周期也就结束了 //内存管理原则什么作用范围内创建就在什么范围内释放 [obj1 release]; //obj1指向的堆内存对象的应用计数减1,此时引用计数为1,此时的引用计数的所有者为obj2的retainOject属性 [obj2 release]; //obj2指向的堆内存对象的应用计数减1,此时引用计数为1,此时的引用计数的所有者为obj1的retainOject属性 // 这个函数都结束了,堆内存中还存在两个相互引用的对象,没有栈上的指针变量引用它们,无法获得它们,就无法释放它们,这样就找出了内存泄漏
2015-01-18 00:12:13.260 MemoryManager[1186:56593] before
2015-01-18 00:12:13.260 MemoryManager[1186:56593] obj1 retainCount=1 obj2 retainCount=1
2015-01-18 00:12:13.261 MemoryManager[1186:56593] after
2015-01-18 00:12:13.261 MemoryManager[1186:56593] obj1 retainCount=2 obj2 retainCount=2
Block_copy(<#...#>)也会造成循环应用,如果在block中使用了一些block外部的变量,你需要通过__weak来修饰弱引用这样才不会造成循环引用。
如:
__weak ViewController *weakVc = self; dispatch_async(dispatch_get_main_queue(), ^{ weakVc.view.backgroundColor =[UIColor redColor]; });
二.属性被copy,retain,strong,assign修饰的含义
#import <Foundation/Foundation.h>@interface CycleRetain : NSObject@property (nonatomic,assign)id retainObject;@end
CycleRetain *obj1 = [[CycleRetain alloc]init];//此时 obj1指向的堆对象的引用计数为1 CycleRetain *obj2 = [[CycleRetain alloc]init];//此时 obj2指向的堆对象的引用计数为1 NSLog(@"before "); NSLog(@"obj1 retainCount=%ld obj2 retainCount=%ld",obj1.retainCount,obj2.retainCount); obj1.retainObject = obj2; //因为retainObject是assign属性所以obj2指向的堆内存对象的引用计数此时为1 obj2.retainObject = obj1; //因为retainObject是assign属性所以obj1指向的堆内存对象的引用计数此时为1 NSLog(@"after"); NSLog(@"obj1 retainCount=%ld obj2 retainCount=%ld",obj1.retainCount,obj2.retainCount);
MemoryManager[633:14446] obj1 retainCount=1 obj2 retainCount=1
- iOS-内存管理就这么简单2
- iOS-内存管理就这么简单1
- iOS-防止GDB挂起(就这么简单)
- IOS 简单内存管理
- 社会,就这么简单
- 正则就这么简单
- 一切就这么简单
- 爱,就这么简单
- ERP就这么简单
- SqlHelper就这么简单
- 就这么简单
- SqlHelper就这么简单
- iOS-内存管理简单介绍
- 删除文件就这么简单
- 线程安全,就这么简单
- 入侵ADSL,就这么简单
- 爱,原来就这么简单
- 线程安全,就这么简单
- is not allowed to connect to this MySql server
- java 集合类学习笔记
- 十七、斐波那契数列 【递推思想(迭代思想)解决】
- 关于“性能计数器注册表单元配置一致性”检测失败解决办法
- LeetCode Container With Most Water
- iOS-内存管理就这么简单2
- 泰勒公式(泰勒展开式,泰勒中值定理)使用基本技巧
- SQL数据库“正在恢复”,解决和查看方法
- apache django 配置
- 游戏开发中的人工智能 复习
- 黑马程序员—数组
- zookeeper基本原理
- C语言课设-房产信息统计与分析
- java对象之初始化和清理(1)