//管理内存有三种方式,//1.是垃圾回收,java常见的管理内存的方法,系统来检測对象是否被使用,是否被释放//2.MRC手动管理引用计数,iOS管理内存的方式,程序猿通过手动的方式来管理对象是否被释放//3.ARC自己主动管理引用计数,基于MRC,系统自己主动的管理内存,以后我们还是先使用MRC,培养管理内存的习惯

//
//  Girl.h
//  OC08,09_内存管理
//
//  Created by dllo on 15/7/27.
//  Copyright (c) 2015年 zhozhicheng. All rights reserved.
//#import <Foundation/Foundation.h>
//1.声明协议
@protocol GirlDelegate <NSObject>@required
-(void)married;@optional
-(void)cook;
@end@interface Girl : NSObject
//2.声明代理人属性
@property(nonatomic,assign)id<GirlDelegate>delegate;-(void)getMarry;@end//
//  Girl.m
//  OC08,09_内存管理
//
//  Created by dllo on 15/7/27.
//  Copyright (c) 2015年 zhozhicheng. All rights reserved.
//#import "Girl.h"@implementation Girl
-(void)getMarry{[self.delegate cook];
}@end
//
//  Boy.h
//  OC08,09_内存管理
//
//  Created by dllo on 15/7/27.
//  Copyright (c) 2015年 zhozhicheng. All rights reserved.
//#import <Foundation/Foundation.h>
#import "Girl.h"
@interface Boy : NSObject<GirlDelegate,NSCopying>-(void)dealloc;+(Boy*)boy;@property(nonatomic,retain)NSString *name;
@property(nonatomic,copy)NSString *hobby;
@property(nonatomic,retain)Girl *girls;//自己定义的初始化方法
-(instancetype)initWithName:(NSString *)namehobby:(NSString *)hobby;
+(Boy *)boyWithName:(NSString *)namehobby:(NSString *)hobby;@end//
//  Boy.m
//  OC08,09_内存管理
//
//  Created by dllo on 15/7/27.
//  Copyright (c) 2015年 zhozhicheng. All rights reserved.
//#import "Boy.h"@implementation Boy-(void)cook{NSLog(@"做饭吃");
}-(void)dealloc{NSLog(@"对象被释放了");//把成员变量全部+1操作全部减去[_name release];[_girls release];[_hobby release];[super dealloc];
}+(Boy*)boy{Boy *b=[[Boy alloc] init];return [b autorelease];
}
//id是void *
//id是泛型指针,能够用在不论什么方法中,可是instancetype代表实例类型,用在自己定义初始化方法,便利构造器作为返回值类型使用,标识方法会返回一个对象回去
//-(instancetype)init{//   Boy *b=[[Boy alloc] init];
//    return [b autorelease];
//}- (id)copyWithZone:(NSZone *)zone{Boy *b=[Boy allocWithZone:zone];b.hobby=_hobby;b.name=_name;return b;}-(instancetype)initWithName:(NSString *)namehobby:(NSString *)hobby{[super self];if (self) {self.name=name;   //从直接赋值变成方法赋值_hobby=hobby;}return self;
}+(Boy *)boyWithName:(NSString *)namehobby:(NSString *)hobby{Boy *b=[[Boy alloc] initWithName:name hobby:hobby];//写便利构造器最后别忘了autoreleasereturn [b autorelease];
}-(void)setName:(NSString *)name{if(_name!=name);[_name release];_name=[name retain];
}@end

对象被创建出来之后他的引用计数retainCount就变成1

Boy *boy=[[Boy alloc] init];
NSLog(@"%ld",boy.retainCount);

结果

2015-07-27 17:47:40.331 OC08,09_内存管理[1562:152231] 1

//对对象的引用计数进行+1的操作

// //retain:对对象的引用计数进行+1

Boy *boy=[[Boy alloc] init];
NSLog(@"%ld",boy.retainCount);
[boy retain];
NSLog(@"%ld",boy.retainCount);
[boy retain];
[boy retain];
NSLog(@"%ld",boy.retainCount);

结果

2015-07-27 17:50:13.304 OC08,09_内存管理[1571:153537] 1
2015-07-27 17:50:13.305 OC08,09_内存管理[1571:153537] 2
2015-07-27 17:50:13.305 OC08,09_内存管理[1571:153537] 4

//release:对对象的引用计数进行-1的操作

[boy release];
NSLog(@"%ld",boy.retainCount);
[boy release];
[boy release];
[boy release];
NSLog(@"%ld",boy.retainCount);

结果

2015-07-27 17:54:44.714 OC08,09_内存管理[1580:155505] 1
2015-07-27 17:54:44.715 OC08,09_内存管理[1580:155505] 对象被释放了
2015-07-27 17:54:44.715 OC08,09_内存管理[1580:155505] 1

凝视

//     //假设多次对对象进行释放,会造成过度释放,过度释放也是最常见的内存问题(+1次数小于-1次数)
//    //[boy release];
//    //当对象的引用计数1->0时,会自己主动调用dealloc方法,dealloc才是相应对象释放的方法
//当对象调用release的时候,他的引用计数是1,这个对象就不再对他的引用计数进行-1操作,而是直接调用dealloc方法,所以我们在訪问对象引用计数还是1

几个不同类型retain值

NSArray *arr=@[@"1",@"2",@"3",@"4"];
NSLog(@"%ld",arr.retainCount);NSString *str=@"1111";
NSLog(@"%ld",str.retainCount);NSMutableString *str2=[NSMutableString stringWithString:@"111111"];
NSLog(@"%ld",str2.retainCount);NSDictionary *dic=@{@"1":@"2",@"3":@"4"};
NSLog(@"%ld",dic.retainCount);
NSLog(@"%p",str);
NSLog(@"%p",str2);

结果

2015-07-27 17:56:31.134 OC08,09_内存管理[1587:156279] 1
2015-07-27 17:56:31.134 OC08,09_内存管理[1587:156279] -1
2015-07-27 17:56:31.135 OC08,09_内存管理[1587:156279] 1
2015-07-27 17:56:31.135 OC08,09_内存管理[1587:156279] 1
2015-07-27 17:56:31.135 OC08,09_内存管理[1587:156279] 0x100002130
2015-07-27 17:56:31.135 OC08,09_内存管理[1587:156279] 0x100112ac0

凝视

NSString 的对象在全局静态区,他的引用计数是-1,代表正整数的最大值,其它的对象都在堆区,

Boy *boy=[[Boy alloc] init];
[boy retain];
[boy retain];
NSLog(@"%ld",boy.retainCount);
//release立即会把对象的引用计数-1,可是autorelease会延迟对对象的计数-1
[boy release];
NSLog(@"%ld",boy.retainCount);
[boy autorelease];
NSLog(@"%ld",boy.retainCount);
//自己主动释放池
//仅仅要对象用autorelease释放会把对象放入到系统的自己主动释放池中,等出了池子范围,对象引用计数自己主动-1,这个相当于java的垃圾回收,对象释放由系统来管理@autoreleasepool {[boy autorelease];NSLog(@"%ld",boy.retainCount);}NSLog(@"%ld",boy.retainCount);

结果

2015-07-27 19:00:44.667 OC08,09_内存管理[1602:162429] 3
2015-07-27 19:00:44.668 OC08,09_内存管理[1602:162429] 2
2015-07-27 19:00:44.668 OC08,09_内存管理[1602:162429] 2
2015-07-27 19:00:44.668 OC08,09_内存管理[1602:162429] 2
2015-07-27 19:00:44.668 OC08,09_内存管理[1602:162429] 1

// 内存管理原则:加多少减多少,加减做到平衡,减多了过度释放,降低了没有得到释放

//对象的全部权:拥有全部权的对象能够对他进行release

Boy *b=[Boy boy];
[b retain];
NSLog(@"%ld",b.retainCount);
[b release];

结果

2015-07-27 19:05:11.838 OC08,09_内存管理[1610:164027] 2
 //便利构造器在返回对象的时候会加上一个autorelease,所以用便利构造器创建对象不须要对内存进行管理
NSArray *arr1=[[NSArray alloc] initWithObjects:@"1",@"2", nil];
NSArray *arr2=[NSArray arrayWithObjects:@"1",@"2",nil];
[arr1 release];
    NSArray *arr=@[@"1",@"2",@"3",@"4"];NSArray *newArr=[NSArray arrayWithArray:arr];NSLog(@"%@",newArr);NSLog(@"%ld",arr.retainCount);NSLog(@"%ld",newArr.retainCount);

结果

2015-07-27 19:07:04.008 OC08,09_内存管理[1624:164855] (1,2,3,4
)
2015-07-27 19:07:04.009 OC08,09_内存管理[1624:164855] 1
2015-07-27 19:07:04.010 OC08,09_内存管理[1624:164855] 1

//把一个不可变的变成可变的

NSArray *arr=@[@"1",@"2",@"3",@"4"];
NSMutableArray *arr1=[NSMutableArray arrayWithArray:arr];NSMutableArray *arr2=[arr mutableCopy];
[arr2 addObject:@"5"];
NSLog(@"%@",arr2);NSDictionary *dic=@{@"1":@"2",@"3":@"4"};
NSMutableDictionary *dic1=[dic mutableCopy];
NSLog(@"%@",dic1);

结果

2015-07-27 19:08:34.111 OC08,09_内存管理[1633:165509] (1,2,3,4,5
)
2015-07-27 19:08:34.112 OC08,09_内存管理[1633:165509] {1 = 2;3 = 4;
}

凝视

//系统的类要是实现copy功能,必须先签订拷贝NSCopying协议,然后实现相应的方法
//不可变的数组字典能够通过mutableCopy转换成可变的数组字典
//mutableCopy出来的对象可变,copy是不可变的

举例

Girl Boy文件

//
//  Girl.h
//  OC08,09_内存管理
//
//  Created by dllo on 15/7/27.
//  Copyright (c) 2015年 zhozhicheng. All rights reserved.
//#import <Foundation/Foundation.h>
//1.声明协议
@protocol GirlDelegate <NSObject>@required
-(void)married;@optional
-(void)cook;
@end@interface Girl : NSObject
//2.声明代理人属性
@property(nonatomic,assign)id<GirlDelegate>delegate;-(void)getMarry;@end//
//  Girl.m
//  OC08,09_内存管理
//
//  Created by dllo on 15/7/27.
//  Copyright (c) 2015年 zhozhicheng. All rights reserved.
//#import "Girl.h"@implementation Girl
-(void)getMarry{[self.delegate cook];
}@end//
//  Boy.h
//  OC08,09_内存管理
//
//  Created by dllo on 15/7/27.
//  Copyright (c) 2015年 zhozhicheng. All rights reserved.
//#import <Foundation/Foundation.h>
#import "Girl.h"
@interface Boy : NSObject<GirlDelegate,NSCopying>-(void)dealloc;+(Boy*)boy;@property(nonatomic,retain)NSString *name;
@property(nonatomic,copy)NSString *hobby;
@property(nonatomic,retain)Girl *girls;//自己定义的初始化方法
-(instancetype)initWithName:(NSString *)namehobby:(NSString *)hobby;
+(Boy *)boyWithName:(NSString *)namehobby:(NSString *)hobby;@end//
//  Boy.m
//  OC08,09_内存管理
//
//  Created by dllo on 15/7/27.
//  Copyright (c) 2015年 zhozhicheng. All rights reserved.
//#import "Boy.h"@implementation Boy-(void)cook{NSLog(@"做饭吃");
}-(void)dealloc{NSLog(@"对象被释放了");//把成员变量全部+1操作全部减去[_name release];[_girls release];[_hobby release];[super dealloc];
}+(Boy*)boy{Boy *b=[[Boy alloc] init];return [b autorelease];
}
//id是void *
//id是泛型指针,能够用在不论什么方法中,可是instancetype代表实例类型,用在自己定义初始化方法,便利构造器作为返回值类型使用,标识方法会返回一个对象回去
//-(instancetype)init{//   Boy *b=[[Boy alloc] init];
//    return [b autorelease];
//}- (id)copyWithZone:(NSZone *)zone{Boy *b=[Boy allocWithZone:zone];b.hobby=_hobby;b.name=_name;return b;}-(instancetype)initWithName:(NSString *)namehobby:(NSString *)hobby{[super self];if (self) {self.name=name;   //从直接赋值变成方法赋值_hobby=hobby;}return self;
}+(Boy *)boyWithName:(NSString *)namehobby:(NSString *)hobby{Boy *b=[[Boy alloc] initWithName:name hobby:hobby];//写便利构造器最后别忘了autoreleasereturn [b autorelease];
}-(void)setName:(NSString *)name{if(_name!=name);[_name release];_name=[name retain];
}@end

执行

//Boy类使用Copy的方法Boy *boy=[Boy boyWithName:@"张阳阳" hobby:@"玩"];Boy *newBoy=[boy copy];NSLog(@"%@",newBoy.name);//假设自己的类想要实现copy功能,就必须先签订NSCopying协议,然后实现相应的协议方法,initWithZone,之后就能够使用copy的功能NSLog(@"%ld",boy.retainCount);NSLog(@"%ld",newBoy.retainCount);

结果

2015-07-27 19:13:02.102 OC08,09_内存管理[1644:168242] 张阳阳
2015-07-27 19:14:15.390 OC08,09_内存管理[1653:168927] 1
2015-07-27 19:14:15.390 OC08,09_内存管理[1653:168927] 1
    Boy *boy1=[[Boy alloc] init];[boy1 retain];[boy1 retain];NSLog(@"%ld",boy1.retainCount);NSMutableArray *arr=[NSMutableArray arrayWithObjects:boy1, nil];NSLog(@"%ld",[arr[0] retainCount]);

结果

2015-07-27 19:14:52.821 OC08,09_内存管理[1660:169279] 3
2015-07-27 19:14:52.822 OC08,09_内存管理[1660:169279] 4

凝视

// 当对象放入到容器Array或者字典中,对面会被容器进行一次持有,就是retain一次,他的引用计数会+1,主要是为了防止空指针的问题
// //等对象从容器移除掉之后,相应的会-1

    Boy *b=[[Boy alloc] init];Girl *girl=[[Girl alloc]init];b.girls=girl;NSLog(@"%ld",girl.retainCount);Girl *girl2=[[Girl alloc] init];b.girls=girl2;NSLog(@"%ld",girl.retainCount);

结果

2015-07-27 19:16:00.235 OC08,09_内存管理[1667:169909] 2
2015-07-27 19:16:00.236 OC08,09_内存管理[1667:169909] 1

一个完整的类写法

//
//  Person.h
//  OC08,09_内存管理
//
//  Created by dllo on 15/7/27.
//  Copyright (c) 2015年 zhozhicheng. All rights reserved.
//#import <Foundation/Foundation.h>@interface Person : NSObject@property(nonatomic,retain)NSMutableArray *arr;
@property(nonatomic,copy)NSString *name;
@property(nonatomic,assign)NSInteger age;-(id)initWithName:(NSString *)nameage:(NSInteger)age;+(Person *)personWithName:(NSString *)nameage:(NSInteger)age;@end
//
//  Person.m
//  OC08,09_内存管理
//
//  Created by dllo on 15/7/27.
//  Copyright (c) 2015年 zhozhicheng. All rights reserved.
//#import "Person.h"@implementation Person-(id)initWithName:(NSString *)nameage:(NSInteger)age{self=[super init];if (self) {self.name=name;self.age=age;//对象创建之后,里面的数组也会创建好,不用在外面进行创建,避免由于忘了,造成问题self.arr=[NSMutableArray array];}return self;
}+(Person *)personWithName:(NSString *)nameage:(NSInteger)age{Person *per=[[Person alloc] initWithName:name age:age];return [per autorelease];}
-(void)dealloc{[_arr release];[_name release];//age是栈区的,我们操作的是堆区
}@end
    Person *per=[[Person alloc] initWithName:@"张阳阳" age:20];[per.arr addObject:@"1" ];NSLog(@"%@",per.arr);

结果

2015-07-27 19:18:09.427 OC08,09_内存管理[1675:171354] (1
)

iOS OC08,09_内存管理相关推荐

  1. iOS/OS X内存管理(一):基本概念与原理

    iOS/OS X内存管理(一):基本概念与原理 发表于21小时前| 1585次阅读| 来源CSDN| 8 条评论| 作者刘耀柱 移动开发iOSObjective-C内存管理内存泄露局部变量开发经验 a ...

  2. iOS/OS X内存管理(二):借助工具解决内存问题

    上一篇博客<iOS/OS X内存管理(一):基本概念与原理>主要讲了iOS/OS X内存管理中引用计数和内存管理规则,以及引入ARC新的内存管理机制之后如何选择ownership qual ...

  3. iOS开发ARC内存管理技术要点

    本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automatic Reference Counting,自动引用计数)内存管理技术的要点,所以不会涉及全部细节.这篇 ...

  4. iOS开发ARC内存管理

    本文的主要内容: ARC的本质 ARC的开启与关闭 ARC的修饰符 ARC与Block ARC与Toll-Free Bridging ARC的本质 ARC是编译器(时)特性,而不是运行时特性,更不是垃 ...

  5. iOS夯实:内存管理

    最近的学习计划是将iOS的机制原理好好重新打磨学习一下,总结和加入自己的思考. 有不正确的地方,多多指正. 基本信息 Objective-C 提供了两种内存管理方式. MRR (manual reta ...

  6. iOS开发经验总结—内存管理

    From: http://ihuby.info/2011/07/18/ios%E5%BC%80%E5%8F%91%E7%BB%8F%E9%AA%8C%E6%80%BB%E7%BB%93-%E5%86% ...

  7. (0048)iOS开发之内存管理探究

    注意网上很多人支招在ARC模式下可以利用_objc_rootRetainCount()或者CFGetRetainCount()取得 retainCount都是不准确的,特别是在对象拷贝操作之后你会发现 ...

  8. iOS的block内存管理

    初始情况下: block本身.__block修饰的变量以及在block内部使用的变量都是在栈里的. __block修饰的变量的地址会作为实参传入block块内部(暂时先这么理解,实际比较复杂).blo ...

  9. multiprocessing.manager管理的对象需要加锁吗_iOS内存管理布局-理论篇

    苹果设备备受欢迎的背后离不开iOS优秀的内存管理机制,那iOS的内存布局及管理方案是怎样的呢?我们一起研究下. 内存管理分为五大块 栈区(stack):线性结构,内存连续,系统自己管理内存,程序运行记 ...

最新文章

  1. 学生信息管理系统小结
  2. 音视频技术开发周刊 | 138
  3. 读 《CSharp Coding Guidelines》有感
  4. jzoj2292-PPMM【模拟,堆】
  5. Mac pycharm flask 用内网ip 运行 web
  6. iperf测试网卡性能
  7. Unity Application Block 3月12 发布的版本
  8. EPOLL AND Nonblocking I/O
  9. 企业的IT 建设的三个过程
  10. 电离层对高分辨率星载SAR成像的影响1——电离层的相关定义
  11. 鸿蒙安卓字体,鸿蒙中如何自定义字体文件
  12. LINUX编译xcb/xcb-proto
  13. 2019八泉峡第二届国际露营大会圆满落幕 创新举措引爆景区
  14. protobuf c语言版本
  15. 基于人工智能的图像处理技术:利用Opencv实现
  16. 2022“杭电杯”中国大学生算法设计超级联赛(8)补题
  17. Flink 窗口函数(Window Functions)处理迟到数据
  18. cf12月9日服务器维护时间,cf12月9、10日全区全服维护更新公告_穿越火线更新公告_7k7k穿越火线...
  19. gataway服务无法注册进eureka
  20. docker swam 安装kafka集群以及kfakamanger

热门文章

  1. 基于 vue.js 的仿QQ聊天室
  2. Compound 治理——提案
  3. 《STM32从零开始学习历程》——CAN通讯协议协议层
  4. 【Java核心】详解Java中断机制
  5. 一场属于HTML5守望者的盛宴——记图灵参加HTML5峰会
  6. Windows安装sql Server2016
  7. 计算机网络 四、五层协议体系结构-----数据链路层
  8. python自动化客户端_如何使用Python自动化登录客户端,pywinauto确实很强大
  9. 深圳大学计系汇编语言实验--四子棋游戏
  10. VA525紧凑型嵌入式流量计0695 5250_A1_B1_C1_D1_E1_F1_G1_H1_I1_J1_K1_L1_M1_R1