Object-C连载九----内存管理

一.什么是内存管理
  OC 中的内存管理只针对 OC 中的对象,所有的对象都继承 NSObject ,都是一小块内存指向一大块内存
 
基本数据类型不需管理内存 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:
基本数据类型,结构体,代理对象
  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的黄金法则:
   只要还有一个变量(指针)指向对象,对象就会保持在内存中
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 );

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值