注:小编在技术上还是有很大的纰漏,发表此博客希望各位有路过的大牛人物给予评论,给于指正,小编在此非常感谢!此文章为小编自己做的笔记,有不当之处望请指出,小编很是感谢,若用于一些抄袭的勾当,出现一些不可挽回的问题,小编在此声明不负任何责任;
内存管理
对象的生命周期包括以下几个时期:
对象初始化——>对象接收消息和执行操作——>对象被释放;
判断一个对象是否结束,用到引用计数器;(引用计数器的基本概念)
1、每个人对象有一个整数值,这个整数值与对象本身关联,称为引用计数器;
2、当某些地方需要使用这个对象时,可以将引用计数器加1,表示使用这个这个对象;
3、使用完毕后,将该对象的引用计数器值减1;表示该对象已经使用完毕;
4、如果引用计数器为0时,表示没有地方再使用该对象了,这是系统将销毁该对象,其所占内存被收回,以便重用;
ARC、MRC
1、ARC自动管理引用计数(系统默认,当前实际开发 全部使用的时ARC)
2、MRC手动管理引用计数
一、手动计数:
怎么去操作引用计数;
1、什么时候才能让引用计数加1?
当使用alloc、new、copy、retain、引用计数加1;
2、什么时候才能让引用计数减1;
当使用release、引用计数减1;
引用计数 是判断这个对象是否被销毁的依据;
为什么使用retain?
为了防止对象被销毁(引用计数为0的时候会被销毁);
3、当引用计数 为0的时候 销毁对象的时候会调用delloc方法;
delloc方法不能够直接调用,,是系统自动调用的;
1、对象引用计数为0,(对象已经被销毁的时候)对象是一个野指针(没有指向任何东西的指针)
2、使用这个野指针 再去调用方法或者其他操作 会直接崩溃 或者 存在潜在危险(数据为空);
3、如果对象的引用计数为0,就不要强制给这个对象return;
4、分配在栈里面的不用管理引用计数的:基本数据类型、alloc、new、cope、retain、都不用管理引用计数
总结的思想就是:谁分配,谁释放;
二、自动计数;
自动释放
1、autorelease 延迟释放;
2、经常和自动释放池 配合使用;
3、NSAutoreleasePool是自动释放池的类;
4、也需要对自动释放池 实例化对象 release
5、当不知道什么时候对象不再需要使用 可以使用延迟释放autorelease 延迟释放;
6、放到自动释放池里面;
7、新写法@autoreleasepool{}的生命周期
1)出了花括号自动释放池结束,会触发autorelease里面所有的内容;
8、除了基本数据类型都用retain;
1)nonatomic非原子类型,在多线程的情况下,不保证在不同线程数据的安全;
@property (nonatomic,retain)Dog *dog;
atomic 原子类型,在多线程的情况下,保证数据的安全;
2)assign 基本数据类型使用assign
@property (nonatomic,assign) int age;
9、ARC情况下,如果这个对象在 内存不足 的时候允许它被 销毁掉用unsafe_unretained
10、ARC情况下,如果这个对象在 内存不足 的时候不允许它被 销毁掉用strong,
11、通过引用计数 来判断是否需要销毁这个对象;
alloc、retain、copy、new、引用计数+1;
release、autorelease 引用计数-1;
12、写在自动释放池生命周期以内的 带有延迟释放的 对象 都会在释放池生命周期 结束之后 释放
13、花括号结束之后就是新写法自动释放的生命周期,, 结束的时候;
@autoreleasepool {
Person *xiaohuang = [[[Person alloc]init]autorelease];
}
注:@autoreleasepool是和 autorelease搭配使用的
1)局部变量的生命周期;
定义的位置 知道定义位置存在的括号以内
2)全局变量的生命周期;
在对象存在的时候就可以使用
14、 分配在栈里面的数据 不需要程序员去管理内存;
分配在堆里面的数据 需要程序员去管理内存;
15、属性 setter、getter 方法的内存管理;
1)_name 现在就是main函数里面实例化的nameContent这个跟对象
2)如果_name的retainCount在释放之前是1,调用release之后 就会销毁_name这个对象;
15、[_dog release];//或者[self.dog release];
16、retain copy 的区别
retain是给原来对象的引用计数+1;
copy会生成一个新的对象;给新的引用计数+1;
17、自定义拷贝
除了字符串、字典、数组、NSNumber 都需要自定义拷贝 的功能,(遵守拷贝协议);
18、深浅拷贝
深拷贝 是完全拷贝一个对象,这个对象与原来的对象完全是两个个体;内存地址不一样
浅拷贝 是只拷贝对象本身,不拷贝对象里面的内容; 内存地址一样
19、判断深浅拷贝的依据:
看他们(不只是对象的本身,也包含对象里面具体的内容)的内存地址是否一致;
注:
1)如果想让一个不可变对象 变成 可变对象 可以使用 mutableCopy
NSArray *list = @[@"dsa",@"fgdg",@"ewqe"];
NSMutableArray *muArray = [list mutableCopy];
// 在此可以使用移除、添加、替换;
[muArray removeLastObject];
NSLog(@"%@",muArray);
2)如果一个可变的对象 进行copy 它将变成一个不可变的对象;
/*
NSMutableString *string = [NSMutableString stringWithString:@"fdsfdsaga"];
NSMutableString *stri = [string copy];
[stri appendString:@"aaaaaaa"];
NSLog(@"%@",stri);
*/
扩展:
NSOrderedAscending在左侧的比较值小于右侧的值;
NSOrderedDescending右侧的值小于左侧值;
c可用于判断比较的两个值相等;