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

本文深入探讨Objective-C中的内存管理机制,包括引用计数、黄金法则、自动释放池的应用,以及如何避免循环引用导致的内存泄漏。通过实例代码演示,详细解释对象生命周期与内存管理的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.什么是内存管理
  OC中的内存管理只针对OC中的对象,所有的对象都继承NSObject,都是一小块内存指向一大块内存
 
基本数据类型不需管理内存intfloatchardoublelongstrut
 
当一个对象没有人再使用,该对象应该从内存中销毁
  alloc
开辟的都在堆区,栈区会自动管理而堆区不能
二.
引用计数
 
所有的OC对象都有一个计数器,这个计数器我们称为引用计数
 
引用计数表示有几个人在使用当前对象
 
每个对象都有一个retainCount引用计数,表示当前对象被引用的数量(用retainrelease进行加减)
三.
黄金法则
 
如果对一个对象使用了alloc[butable]copyretain,那么必须使用相应的releaseautorelease释放
 
四.copy
  copy
是开辟了一个新的内存空间,但内容相同
 
深拷贝[butable]copy:拷贝出来的不仅仅是指向,还包括指向的对象的地址
 
浅拷贝:只拷贝对象而不拷贝其所对应的地址
  对于Foundation框架中的不可变类型使用copy[butable]copy是一样的,没什麽区别
  对于自身去实现copy方法,一定要实现copy协议(copywithzoo这个不明白可以暂时不管)

五.@propoty
  基本语法:propoty nanomaticcopy/asign/retain)数据类型 *属性名

  copy:字符串
  assign:
基本数据类型,结构体,代理对象
  retain:对象
(1)使用@property,可为一个属性自动生成set、get方法,并且,.h文件中实例变量的定义也可以不写。
(2)凡是写property并且有多个属性的地方,如果要同时复写setget方法,则必须要加实例属性变量。
(3)若使用了@property,又复写了set或get方法,则复写的优先级比@property的优先级高。
(4)类目中可以用property,但必须在.m文件中实现setget方法
(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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值