博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Objective-C:内存管理的小结
阅读量:6679 次
发布时间:2019-06-25

本文共 4525 字,大约阅读时间需要 15 分钟。

内存管理:

1、OC的对象都是分配在堆里的
     Perosn *person  = [[Person alloc]init];
     Person *person       //指针类型的变量,放在栈里。
     [[Person alloc]init]   //在堆里创建的对象,并初始化。
     真正的含义: 用指针变量指向了堆中创建出来的对象
 
     Person *person2 = person; //person2和person都指向了同一个对象
 
2、堆里的对象应该是谁创建,就该是谁释放。系统释放模式分为两种:
     ARC 自动引用计数 (系统帮助完成内存的释放)
     MRC 手动引用计数 (人为帮助完成内存的释放)
MRC:

对于对象类型的实例变量,可以使用@property自动生成相应地存取方法,

但@property中必须要采用retain的内存设置;

assign用于基本的数据类型,不需要获取所有权的类型。

 ARC:

 strong 相当于MRC中的retain

 assign 用于基本的数据类型

 weak   不需要获取所有权的对象类型

 unsafeunretain 用在不支持weak的旧版本中

     
3、什么是引用计数?
     程序中会出现多个指针指向同一个对象的情况。这种情况下要保证不能提前释放这个对象,必须在所有的指针都不再使用这个对象时候才能释放对象。
     计数器:retainCount     -(unsigned)retainCount;
     对象中存储被引用的次数,
     当被引用的时候,计数器加1;  -(id)retain;    retainCount+1
     不在引用的时候,计数器减1;  -(void)release;   retainCount-1
     当计数器为0的时候,真正去销毁对象。-(void)dealloc; 
//可以重写这个方法,但是切记不要直接显式的调用,因为系统在最后会直接调用它,此时
retainCount=0
 
4、对象所有权
       指针指向一个对象时,可以获得对象所有权(引用计数器加1);
       也可以不获得对象所有权(引用计数器不变化)
      ARC:strong,weak,assign       
strong获得对象所有权
      MRC:retain ,assign
       retain获得对象所有权
 
5、引用计数和字符串
内存中的常量字符串的空间分配与其他对象不同,他们没有引用计数机制
凡是自定义的对象都有引用计数机制;
OC内部中对象分为可变对象(NSMutableString等)和不可变对象(NSString、NSArray等),
  
不可变对象不适用于引用计数的机制,可变的对象适用引用计数机制。
 
6、对象之间的循环引用
       两个对象A、B,有可能会出现一种特殊的情况:A中包含B的实例变量;B中又包含A的实例变量,如果两个实例变量都是强引用(A有B实例变量的所有权,B也有A的实例bl的所有权),然后再两个对象销毁时,会出现A、B都不能正常销毁的情况。
 
7、对象复制

对象复制中的浅复制和深复制:

浅复制:复制对象时,如果对象中包含对象类型的实例变量,只是复制指针。新对象中的对象类型实例变量和旧对象中的对象类型实例变量指的是同一个对象。任何一方实例变量对对象做修改,另一方实例变量指向的该对象也就改变了。

深复制:复制对象时,如果对象中包含对象类型的实例变量,要对对象类型的实例变量也要做对象复制。新对象中的对象类型实例变量和旧对象中的对象类型实例变量指的是不同的对象。不管任何一方实例变量对对象做修改,都互相不影响对方所指向的对象的内容。

用网上一哥们通俗的话将就是:

浅复制好比你和你的影子,你完蛋,你的影子也完蛋

深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。

8、自动释放池(管理需要延迟释放的对象)

由new、copy、alloc创建的对象不会自动入池,需要通过发送autorelease消息,将一个对象添加到其中,以便最后释放:[MyFranction autorelease]

 

1 #import 
2 #import "Book.h" 3 void ex1(); 4 void ex2(); 5 void ex3(); 6 void ex4(); 7 void ex5(); 8 int main(int argc, const char * argv[]) 9 {10 //ex1();11 //ex2();12 //ex3();13 //ex4();14 ex5();15 return 0;16 }

 

 

 

1)创建自动释放池的两种方法:

-NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]

[pool release]《==等价于==》[pool drain]; 

1 void ex1() 2 { 3     //创建一个自动释放池对象 4     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 5     //自动释放池的使用 6     Book *book = [[Book alloc]initWithTitle:@"OC" andAuthor:@"Jobs" andPrice:35.6]; 7      8     //将book对象加入自动释放池 9     [book autorelease];10     [book print];11     12     NSLog(@"autorelease last");13     //清空自动释放池--会给每个管理的对象发送release消息14     [pool release];//===[pool drain]15 }

 

或者

-@autoreleasePool

{

}

1 //创建自动释放池的第一种方式 2 void ex2() 3 { 4     @autoreleasepool { 5  6     //自动释放池的使用 7     Book *book = [[Book alloc]initWithTitle:@"OC" andAuthor:@"Jobs" andPrice:35.6]; 8      9     //将book对象加入自动释放池10     [book autorelease];11     [book print];12     13     NSLog(@"autorelease last");14     }//在自动释放池结束时,会给每个管理的对象发送release消息15 }

 

(2)延迟释放对象

在OC的内置类(NSString、NSArray等)中提供的类方法创建的对象实例都是“延迟释放对象”,也就是在对象创建完成后将对象加入自动释放池。

 

1 +(Book*)bookWithTitle:(NSString*)title andAuthor:(NSString*)author andPrice:(CGFloat)price2 {3     return [[[Book alloc]initWithTitle:title andAuthor:author andPrice:price]autorelease];4 }

 

1 void ex3()2 {3     @autoreleasepool {4         //这种对象不需要我们去给它们发release消息。5         Book *book = [Book bookWithTitle:@"OC" andAuthor:@"Jobs" andPrice:35.6];6         [book print];7         //[book release];8     }9 }

 

 

(3)自动释放池的嵌套

    对象在加入自动释放池时,加入的是离它最近的自动释放池,目的是为了让延迟释放的对象尽快得到释放,降低程序运行期间的内存占用;

           在管理多个自动释放池时,采用了类似“栈”的结构,可以让对象轻松的找到离它最近的(栈顶的)自动释放池。

 

1 +(Book*)bookWithTitle:(NSString*)title andAuthor:(NSString*)author andPrice:(CGFloat)price2 {3     return [[[Book alloc]initWithTitle:title andAuthor:author andPrice:price]autorelease];4 }

 

 

 

1 void ex4() 2 { 3     @autoreleasepool { 4         Book *book = [Book bookWithTitle:@"iOS" andAuthor:@"Bill" andPrice:55.6]; 5         [book print]; 6         @autoreleasepool { 7             Book *book2 = [Book bookWithTitle:@"iOS" andAuthor:@"Bill" andPrice:55.6]; 8             [book2 print]; 9         }10     }11 }

 

(4)独立的自动释放池

  当程序中出现创建大量延迟释放对象的代码时,最好给它一个独立的自动释放池,保证这些对象在不用了后马上释放掉

1 +(Book*)bookWithTitle:(NSString*)title andAuthor:(NSString*)author andPrice:(CGFloat)price2 {3     return [[[Book alloc]initWithTitle:title andAuthor:author andPrice:price]autorelease];4 }

 

1 void ex5() 2 { 3     @autoreleasepool { 4         for(int i=0; i<10000; i++) 5         { 6             @autoreleasepool {
//独立的自动释放池 7 Book *book = [Book bookWithTitle:[NSMutableString stringWithFormat:@"book%d",i+1] andAuthor:[NSMutableString stringWithFormat:@"author%d",i+1 ] andPrice:20+i]; 8 [book print]; 9 }10 }11 }12 }

 

 

   

转载地址:http://yinao.baihongyu.com/

你可能感兴趣的文章
day28 classmethod 装饰器
查看>>
jquery 实现弹出框 打开与关闭
查看>>
经典大数据面试题
查看>>
[PTA]带头结点的链式表操作集
查看>>
jedis,spring-redis-data 整合使用,版本问题异常以及解决。
查看>>
LESS 学习整理总结
查看>>
QName
查看>>
makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解【转】
查看>>
》》HTTP 方法:GET 对比 POST《《Java:SpringMVC:基础知识:Http协议:000()
查看>>
ubuntu操作系统下spark源码走读环境搭建
查看>>
LeetCode OJ:Reverse Linked List II(反转链表II)
查看>>
LeetCode OJ:Binary Tree Zigzag Level Order Traversal(折叠二叉树遍历)
查看>>
Web 1三级联动 下拉框 2添加修改删除 弹框
查看>>
海量数据、高并发优化方案
查看>>
会计的思考(35):会计数据之殇
查看>>
10多媒体
查看>>
分布式一致性协议
查看>>
day10-mysql
查看>>
脑洞大开——我理解的编程模式
查看>>
项目总结07:JS图片的上传预览和表单提交(FileReader()方法)
查看>>