内存管理:

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]

 #import <Foundation/Foundation.h>
#import "Book.h"
void ex1();
void ex2();
void ex3();
void ex4();
void ex5();
int main(int argc, const char * argv[])
{
//ex1();
//ex2();
//ex3();
//ex4();
ex5();
return ;
}

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

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

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

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

或者

-@autoreleasePool

{

}

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

(2)延迟释放对象

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

 +(Book*)bookWithTitle:(NSString*)title andAuthor:(NSString*)author andPrice:(CGFloat)price
{
return [[[Book alloc]initWithTitle:title andAuthor:author andPrice:price]autorelease];
}
 void ex3()
{
@autoreleasepool {
//这种对象不需要我们去给它们发release消息。
Book *book = [Book bookWithTitle:@"OC" andAuthor:@"Jobs" andPrice:35.6];
[book print];
//[book release];
}
}

(3)自动释放池的嵌套

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

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

 +(Book*)bookWithTitle:(NSString*)title andAuthor:(NSString*)author andPrice:(CGFloat)price
{
return [[[Book alloc]initWithTitle:title andAuthor:author andPrice:price]autorelease];
}
 void ex4()
{
@autoreleasepool {
Book *book = [Book bookWithTitle:@"iOS" andAuthor:@"Bill" andPrice:55.6];
[book print];
@autoreleasepool {
Book *book2 = [Book bookWithTitle:@"iOS" andAuthor:@"Bill" andPrice:55.6];
[book2 print];
}
}
}

(4)独立的自动释放池

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

 +(Book*)bookWithTitle:(NSString*)title andAuthor:(NSString*)author andPrice:(CGFloat)price
{
return [[[Book alloc]initWithTitle:title andAuthor:author andPrice:price]autorelease];
}
 void ex5()
{
@autoreleasepool {
for(int i=; i<; i++)
{
@autoreleasepool {//独立的自动释放池
Book *book = [Book bookWithTitle:[NSMutableString stringWithFormat:@"book%d",i+] andAuthor:[NSMutableString stringWithFormat:@"author%d",i+ ] andPrice:+i];
[book print];
}
}
}
}

Objective-C:内存管理的小结的更多相关文章

  1. Objective C内存管理之理解autorelease------面试题

    Objective C内存管理之理解autorelease   Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的A ...

  2. Objective C 内存管理[转]

    1  配对原则 alloc – release new – release retain - release copy – release 2  new和alloc-init的区别 (1)区别只在于a ...

  3. 黑马程序员——OC的内存管理学习小结

    内存管理在Objective-C中的重要性就像指针在C语言中的重要程序一样. 虽然作为一门高级语言,但OC却没有内存回收机制.这就需要开发者来对动态内存进行管理.OC中内存管理的范围是:任何继承了NS ...

  4. objective C 内存管理及属性方法具体解释

    oc为每一个对象提供一个内部计数器.这个计数器跟踪对象的引用计数,当对象被创建或拷贝时.引用计数为1.每次保持对象时,调用retain接口.引用计数加1.假设不需要这个对象时调用release,引用计 ...

  5. Objective -C Memory Management 内存管理 第一部分

    Objective -C Memory Management  内存管理  第一部分 Memory management is part of a more general problem in pr ...

  6. javascript 变量,作用域,内存管理小结

    js的变量保存两种类型的数据——基本数据类型与引用类型.具有以下几点特征:   变量: 1)基本类型值在内存中占固定大小的空间,因此被保存在栈内存中; 2) 把保存基本类型值得变量赋给另一个变量,会创 ...

  7. Objective-C(内存管理)

    引用计数器 每个OC对象都有一个占4个字节存储空间的引用计数器 当使用或创建一个对象时,新对象的引用计数器默认是1 retain:可以使引用计数器+1 release:可以是引用计数器-1 retai ...

  8. Objective C----手动管理内存和自动管理内存

    对象的引用计数(Reference Counting) 正常情况下,当一段代码需要访问某个对象时,该对象的引用的计数加1:当这段代码不再访问该对象时,该对象的引用计数减1,表示这段代码不再访问该对象: ...

  9. AJPFX的内存管理小结

    管理范围:任何继承于 NSObject的对象原理:每一个对象都有引用计数器当使用alloc new 和 copy创建对象时引用计数器被设置为1给对象发送一条retain消息 ,引用计数器加1     ...

随机推荐

  1. 【转】关于Jmeter3.0,你必须要知道的5点变化

    2016.5.18日,Apache 发布了jmeter 3.0版本,本人第一时间上去查看并下载使用了,然后群里或同事都会问有什么样变化呢?正好在网上看到一遍关于3.0的文章,但是是英文的.这里翻译一下 ...

  2. Ionic Js十四:浮动框

    $ionicPopover $ionicPopover 是一个可以浮在app内容上的一个视图框. 实例 HTML 代码 <p> <button ng-click="open ...

  3. thinkphp3.2局部不缓存的静态缓存

    在thinkphp中,对于访问量大的网站可以用静态缓存来越过数据库瓶颈来提高访问速度,但有时候并不是整个页面都要缓存的,如登录的用户名部分,那么如何实现局部不缓存呢? 其实有多种方法,但对于Think ...

  4. 牛客练习赛3 B - 贝伦卡斯泰露

    链接:https://www.nowcoder.net/acm/contest/13/B来源:牛客网 题目描述 贝伦卡斯泰露,某种程度上也可以称为古手梨花,能够创造几率近乎 为0的奇迹,通过无限轮回成 ...

  5. JQuery实现最字体的放大缩小

    网页常常有对字体放大缩小的需求,我们不妨来看一下下面这段JQuery代码的实现. 假如在html页面代码中我们有这么一段代码: <p>啦啦啦啦啦啦啦啦啦啦</p> 那么JQue ...

  6. ceph journal操作

    查询ceph journal的地方 ceph --admin-daemon /var/run/ceph/ceph-osd.0.asok config show | grep osd_journal & ...

  7. BZOJ 2959: 长跑 lct 双联通分量 并查集 splay

    http://www.lydsy.com/JudgeOnline/problem.php?id=2959 用两个并查集维护双联通分量的编号和合并. #include<iostream> # ...

  8. 洛谷.4252.[NOI2006]聪明的导游(提答 直径 随机化)

    题目链接 随机化 暴力: 随便从一个点开始DFS,每次从之前得到的f[i]最大的子节点开始DFS.f[i]为从i开始(之前)能得到的最大答案. 要注意的是f[i]应当有机会从更小的答案更新, 9.10 ...

  9. 浅谈期望的线性性(可加性)【CodeForces280c】【bzoj3036】【bzoj3143】

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=63399955 向大(hei)佬(e)势力学(di ...

  10. 【Floyd矩阵乘法】BZOJ1706- [usaco2007 Nov]relays 奶牛接力跑

    [题目大意] 给出一张无向图,求出恰巧经过n条边的最短路. [思路] 首先题目中只有100条边,却给出了10000个点(实际上最多只能有200个),离散化一下. 后面就是Floyd的新姿势,以前看过的 ...