Objective-C——内存管理

来源:互联网 发布:360浏览器mac版下载 编辑:程序博客网 时间:2024/05/23 01:56

内存管理总结


———- android培训、java培训、期待与您交流! ———-

  • 内存管理总结
    • 前言
  • 在非ARC 机制下
    • 内存管理的机理
    • 对象的引用计数器
    • 下面介绍Object-C中关于引用计数器的三个对象方法
      • 1retain
      • 2release
      • 3retainCount
    • 需要在set方法中添加的相关代码
      • 1参数为非OC对象的时候
      • 2参数为OC对象的时候
    • property参数初级
      • 1参数为非OC对象的时候
      • 2参数为OC对象的时候
    • autorelease
      • 1系统autorelease过的对象
      • 2创建autorelease过的类方法
  • 在ARC机制下
    • 内存管理的机理
    • ARC特点
  • 循环引用
    • class
    • 开发中引用一个类的规范
    • 两端循环引用解决方案
      • 在非ARC 机制下
      • 在ARC机制下


00.前言

在Object-C中,没有像Java语言一样的垃圾自动回收机制,那么如何提高程序的性能呢?
这就需要我们程序员来对我们所创建出来的对象做适当的回收处理工作,也就是所谓的内存管理。

需要了解的概念
1> 僵尸对象 :所占用内存已经被回收的对象,僵尸对象不能再使用
2> 野指针 :指向僵尸对象(不可用内存)的指针,给野指针发送消息会报错(EXC_BAD_ACCESS)
3> 空指针 :没有指向任何东西的指针(存储的东西是nil、NULL、0),给空指针发送消息不会报错

在非ARC 机制下

0.内存管理的机理

当一个对象被创建出来后,一旦她的引用计数器值为0,那么该对象就会被销毁。
(会调用该对象的dealloc方法)

e.g. :

    - (void)dealloc    {        [othersObj release];        [super dealloc];        }    }
那么问题来了什么是引用计数器呢?

1.对象的引用计数器

在OC程序中,每个被创建的对象都有一个对本对象负责的引用计数器,用来记录该对象被多少个
该类型的指针所引用,当该对象的引用计数器值为1表示该对象被创建

即在对象被分配内存空间(该对象的类调用类方法alloc)并且有该类型的指针对其引用的时候该对象的引用计数器的值会被设置为1;之后每一个对该对象的引用都会让此对象的引用计数器加1,每一次对该对象取消引用操作都会让该对象的引用计数器减1。PS:对象被创建即使没有该类型的指针引用,她的引用计数器的值也会被设为1

2.下面介绍Object-C中关于引用计数器的三个对象方法

1>retain

用法:

[obj retain]

效果: 使该对象(obj)的引用计数器加1

表意:表明该对象(obj)被使用的地方增加1次而这样的操作需要通过调用对象的retain方法来告知引用计数器,
也就是调用retain方法来让其值加1

原则: 谁调用retain方法谁的引用计数器数值加1

使用场合: 其他对象给相关类型的成员变量赋值引用的时候,以及将此对象的引用进行传递的时候需要调用此方法

2>release

用法:

[obj release]

效果: 使该对象(obj)的引用计数器减1

表意:表明该对象(obj)被使用的地方减少1次而这样的操作需要通过调用对象的release方法来告知引用计数器,
也就是调用release方法来让其值减1

原则: 谁调用release方法谁的引用计数器的数值减1

使用场合: 当任意一个指向该对象的指针被置空,或者指向该类型其他对象,
或者任意已指向此变量的指针变量的内存被释放的时候需要调用此方法。

3>retainCount

用法:

NSUInteger count = [obj retainCount];

    PS:在NSObjCRuntime.h中    (typedef unsigned long NSUInteger;)

效果: 取出当前对象(obj)引用计数器的值


3.需要在set方法中添加的相关代码

1>参数为非OC对象的时候

- (void)setAge:(int)age{    _age = age;}

2>参数为OC对象的时候

- (void)setOBJ:(OBJ*)obj{    if(obj != _obj)    {        [_obj release];        _obj = [obj retain];    }}

4.@property参数初级

1>参数为非OC对象的时候

ps: 包括基本数据类型、枚举、结构体(char\int\float\double\tmp[]\enum\strunct)
@property (nonatomic, assign) 类型名称  变量名;@property (nonatomic, assign)   int     age;

2>参数为OC对象的时候

@property (nonatomic, retain) 类名称  *变量名;@property (nonatomic, retain) Person *lostPeople;

5.autorelease

1>系统autorelease过的对象

如果某个对象是通过没有new、alloc 、copy这些方法调用就创建出来的
那么,这些对象就是已经被autorelease过的对象

[NSDate date];

2>创建autorelease过的类方法

开发中经常会需要我们提供一些类方法,快速创建一个已经用过autorelease过的对象,如下所示:

#import "Person.h"@implementation Person+ (id)person{    return [[[self alloc] init] autorelease];}+ (id)personWithStringName:(NSString*) pName{    Person* person = [Person person];    person.name = pName;    return person;}- (void) dealloc{    NSLog(@"Person ...over");    [super dealloc];}@end

在ARC机制下

0.内存管理的机理

任何一个对象只要没有被强指针指所引用,该对象就会被释放

//下面这种写法表明刚创建完Person对象,由于没有被强指针所引用改行执行完毕后Person类型的P对象就会被销毁//即该对象(p)所使用的内存空间会被释放__weak Person *p = [[Person alloc] init];

1.ARC特点

不允许调用release、retain、retainCount

允许重写dealloc,但是不允许调用[super dealloc]

@property的参数
strong :成员变量是强指针(适用于OC对象类型)
weak :成员变量是弱指针(适用于OC对象类型)
assign : 适用于非OC对象类型

以前的retain改为用strong

PS:指针分2种:1> **强指针**:默认情况下,所有的指针都是强指针 __strong2> **弱指针**:__weak

循环引用

1.@class

@class的作用:仅仅告诉编译器,某个名称是一个类

e.g. :

@class Person; // 仅仅告诉编译器,Person是一个类

2.开发中引用一个类的规范

1> 在.h文件中用@class来声明类
2> 在.m文件中用#import来包含类的所有东西

3.两端循环引用解决方案

在非ARC 机制下

1> 一端用retain
2> 一端用assign

在ARC机制下

1> 一端用strong
2> 一端用weak

0 0