内存管理:

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. PHP 统计数据合并

    将不同的统计结果整合在一起,如图,根据年级统计出不同成绩段人数(此处只为举例),然后写了一个方法来处理这些统计数组 <?php /** * 合并统计数据 * @param $key_column ...

  2. MVC设计模式一

    一:基础知识 1.mvc model view control 2.模型 是应用程序的主体部分,模型表示业务数据与业务逻辑. 一个模型可以为多个视图提供数据 提高了代码的可重用性 3.视图 用户看到的 ...

  3. 02:实现Singleton模式

    Java实现单例模式有很多种实现方法,其中我们应根据需要选择线程安全的与非线程安全的两种方式,根据对象实现的方式又分为饱汉与饿汉方式. 这里使用java中的volatile关键字与synchroniz ...

  4. web过滤器使用spring依赖注入

    1.问题描述 在web项目中,使用filter过滤器十分常见,但是在过滤器中spring Bean即使在配置文件中配置了扫描filter对应的包,也无法正确注入spring 管理的Bean. 2.原因 ...

  5. [java] java中的初始化顺序

    先看程序: package init_cls; class A{ {System.out.println("i am in the class A!");} static { Sy ...

  6. [MySQL-笔记]创建高性能索引

    索引,MySQL中也叫“键”,是存储引擎中用于快速找到记录的一种数据结构,具体的工作方式就像书本中的索引一样,但是具体的实现方式会有差别. 一.索引分类 B-Tree索引: 优点: MyISAM中,索 ...

  7. 出现报错: module build failed error couldn't find preset es2015 relative to directory

    当用webpack 进行 build 的时候, 会出现如上标题的错误, 解决方式是在 上级 或者 上上级目录,删除 .babelrc 文件

  8. Opencv学习笔记4:Opencv处理调整图片亮度和对比度

    一.理论基础 在数学中我们学过线性理论,在图像亮度和对比度调节中同样适用,看下面这个公式: 在图像像素中其中: 参数f(x)表示源图像像素. 参数g(x) 表示输出图像像素. 参数a(需要满足a> ...

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

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

  10. Loj #6560 小奇取石子

    题面 分类讨论一波,n小的暴力2^n,n大的背包. #include<bits/stdc++.h> #define ll long long using namespace std; co ...