一.什么是内存管理
OC
中的内存管理只针对
OC
中的对象,所有的对象都继承
NSObject
,都是一小块内存指向一大块内存
基本数据类型不需管理内存 int , float , char , double , long , strut
当一个对象没有人再使用,该对象应该从内存中销毁
alloc 开辟的都在堆区,栈区会自动管理而堆区不能
二. 引用计数
所有的 OC 对象都有一个计数器,这个计数器我们称为引用计数
引用计数表示有几个人在使用当前对象
每个对象都有一个 retainCount 引用计数,表示当前对象被引用的数量(用 retain 和 release 进行加减)
三. 黄金法则
如果对一个对象使用了 alloc 、 [butable]copy 、 retain ,那么必须使用相应的 release 或 autorelease 释放
四.copy
copy 是开辟了一个新的内存空间,但内容相同
深拷贝 [butable]copy :拷贝出来的不仅仅是指向,还包括指向的对象的地址
浅拷贝:只拷贝对象而不拷贝其所对应的地址
基本数据类型不需管理内存 int , float , char , double , long , strut
当一个对象没有人再使用,该对象应该从内存中销毁
alloc 开辟的都在堆区,栈区会自动管理而堆区不能
二. 引用计数
所有的 OC 对象都有一个计数器,这个计数器我们称为引用计数
引用计数表示有几个人在使用当前对象
每个对象都有一个 retainCount 引用计数,表示当前对象被引用的数量(用 retain 和 release 进行加减)
三. 黄金法则
如果对一个对象使用了 alloc 、 [butable]copy 、 retain ,那么必须使用相应的 release 或 autorelease 释放
四.copy
copy 是开辟了一个新的内存空间,但内容相同
深拷贝 [butable]copy :拷贝出来的不仅仅是指向,还包括指向的对象的地址
浅拷贝:只拷贝对象而不拷贝其所对应的地址
对于Foundation框架中的不可变类型使用copy与[butable]copy是一样的,没什麽区别
对于自身去实现
copy
方法,一定要实现
copy
协议(
copywithzoo
这个不明白可以暂时不管)
五.@propoty
基本语法:
propoty
(
nanomatic
,
copy/asign/retain
)数据类型
*
属性名
copy:
字符串
assign: 基本数据类型,结构体,代理对象
assign: 基本数据类型,结构体,代理对象
retain
:对象
(1)使用@
property,可为一个属性自动生成set、get方法,并且,.h文件中实例变量的定义也可以不写。
(2)
凡是写
property
并且有多个属性的地方,如果要同时复写
set
,
get
方法,则必须要加实例属性变量。
(3)若使用了@
property
,又复写了set或get方法,则复写的优先级比@
property
的优先级高。
(4)
类目中可以用
property
,但必须在
.m
文件中实现
set
,
get
方法
(5)
凡是代理问题就用
asign
,解决循环引用问题
六、自动释放池
1.自动释放池是OC的自动管理机制
2.每次RunLoop后会自动释放一次,即计数-1
3.[pool drain]:会对池子中的每一个对象发送release,但池子不会销毁
[pool release]会销毁
4.若是嵌套,在最外层的pool最后release
5.自动释放池是一个容器,通过栈结构进行管理(先进后出原则)
使用[pool autorelease]是错的写法,can’t autorelease an autorelease pool
千万不要在dealloc中使用autorelease
6.新语法与类创建是加入自动释放池,不要[对象 release]
alloc 创建需要[对象 release]
7.将对象添加到数组或字典中,对象会被retain,引用计数+1
将对象移除数组或字典中,对象会被release,引用计数-1
把所有对象都移除,会对容器中的对象发送一条release消息
8.ARC的黄金法则:
5.自动释放池是一个容器,通过栈结构进行管理(先进后出原则)
使用[pool autorelease]是错的写法,can’t autorelease an autorelease pool
千万不要在dealloc中使用autorelease
6.新语法与类创建是加入自动释放池,不要[对象 release]
alloc 创建需要[对象 release]
7.将对象添加到数组或字典中,对象会被retain,引用计数+1
将对象移除数组或字典中,对象会被release,引用计数-1
把所有对象都移除,会对容器中的对象发送一条release消息
8.ARC的黄金法则:
只要还有一个变量(指针)指向对象,对象就会保持在内存中
9.循环引用:
(1)对象A retain 对象B。同时
对象B retain 对象A。———>产生循环引用
(2)循环引用会导致两个对象都无法销毁掉。
10.内存中的区域划分:
//**********
自动释放池
*********************
// 创建一个 dog 对象
Dog *dog1 = [[ Dog alloc ] init ];
[dog1 retain ];
NSLog ( @"dog1 address is %p" ,&dog1);
NSLog ( @"dog1 retainCount is %ld" ,dog1. retainCount );
// 创建一个自动释放池
NSAutoreleasePool *pool1 = [[ NSAutoreleasePool alloc ] init ];
// 将 dog1 放入自动释放池中:
[dog1 autorelease ]; // 放入自动释放池中时, dog1 的引用计数并不会 -1 ,
// 当自动释放池销毁时,才会对池子中的每一个对象发送一条 release 消息
NSLog ( @"dog1 retainCount is %ld" ,dog1. retainCount );
[dog1 release ];
NSLog ( @"dog1 retainCount is %ld" ,dog1. retainCount );
// 自动释放池销毁
// 销毁时,会对池子中的每一个对象发送一条 release 消息
[pool1 release ];
[pool1 drain ]; // 会对池子中的每一个对象发送一条 release 消息,但池子本身不会销毁
NSLog(@"dog1 retainCount is %ld",dog1.retainCount);//Xcode
系统优化的关系
//**********
自动释放池的嵌套使用
***********************
//***** 创建第一个自动释放池
NSAutoreleasePool *pool1 = [[ NSAutoreleasePool alloc ] init ];
// 创建一个 dog 对象
Dog *dog1 = [[ Dog alloc ] init ];
[dog1 retain ];
NSLog ( @"dog1 address is %p" ,&dog1);
NSLog ( @"dog1 retainCount is %ld" ,dog1. retainCount );
// 将 dog1 放入自动释放池中:
[dog1 autorelease ]; // 放入自动释放池中时, dog1 的引用计数并不会 -1 ,
// 当自动释放池销毁时,才会对池子中的每一个对象发送一条 release 消息
NSLog ( @"dog1 retainCount is %ld" ,dog1. retainCount );
//*** 创建第二个自动释放池
NSAutoreleasePool *pool2 = [[ NSAutoreleasePool alloc ] init ];
// 创建一个 dog 对象
Dog *dog2 = [[ Dog alloc ] init ];
[dog2 retain ];
NSLog ( @"dog1 retainCount is %ld" ,dog2. retainCount );
// 将 dog2 放入自动释放池中:(就近原则, dog2 会被放到 pool2 中)
[dog2 autorelease ];
[dog1 release ];
[dog2 release ];
[pool2 release ];
[pool1 release];
//********
快速创建自动释放池
*********************
Dog *dog1;
@autoreleasepool { //<===> [[NSAutoreleasePool alloc]init];
dog1 = [[ Dog alloc ] init ];
[dog1 retain ];
[dog1 autorelease ]; // 一定还要加入到池子中,否则池子销毁时,不会向它发送 release 消息
NSLog ( @"dog1 retainCount is %ld" ,dog1. retainCount );
[dog1 release ];
} //<===> [pool2 release];
NSLog ( @"dog1 retainCount is %ld" ,dog1. retainCount );
Dog *dog1;
@autoreleasepool { //<===> [[NSAutoreleasePool alloc]init];
dog1 = [[ Dog alloc ] init ];
[dog1 retain ];
[dog1 autorelease ]; // 一定还要加入到池子中,否则池子销毁时,不会向它发送 release 消息
NSLog ( @"dog1 retainCount is %ld" ,dog1. retainCount );
[dog1 release ];
} //<===> [pool2 release];
NSLog ( @"dog1 retainCount is %ld" ,dog1. retainCount );