您的位置:首页 > 其它

OC学习笔记-内存管理

2015-10-01 10:46 288 查看
黑马程序员——Objective--C基础笔记之内存管理(一)------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

OC内存管理范围:

管理任何继承NSObject的对象,对其他的数据类型无效。

本质原因是因为对象和其他数据了警在系统中的存储空间不一样,其他局部变量主要存放在栈中,而对象存储于堆中,当代码块结束时,这个代码中设计所有局部变量会被回收,指向对象的指针也会被回收,此时对象已经没有指针指向,但依然存在于内存中,造成泄漏。

内存管理原理及分类

1)对象的所有权饮用计数器

      对象所有权的概念

      任何对象都可能拥有一个或多个所有者,只要一个对象还拥有一个所有者它就会继续存在。

     任何自己创建的对象都归自己所有,可以使用名字以“alloc”或“new”开头或名字中包含“copy”的方法创建对象,      可以使用retain来获得一个对象的所有权。

2)对象的引用计数器(retaincount)

     每个oc对象都有自己的引用计数器,是一个整数表示对象被引用次数,即现在有多少东西在使用这个对象,对象        刚被创建时,默认计数器值为1,当计数器的值变为0时,则对象销毁。

     *在每个oc对象内部,都专门有8个字节的存储空间来存储引用计数器。

3)引用计数器的作用

     引用计数器是判断对象是否要回收的依据(存在一种例外:对象值为nil时,引用计数器为0,但不回收空间)就是      计数器是否为0,若不为0则存在。

4)引用计数器的操作

    给对象发送消息,尽享相应的计数器操作

    retain消息         :使计数器+1,该方法返回对象本身

    release消息       :使计数器-1(并不代表释放对象)

    retaincount消息:获得当前的引用计数器值(%ld,%tu)

5)对象的销毁

当一个对象的引用计数器为0,那么它将销毁,其占用的内存呗系统回收,当对象呗销毁时,系统会自动向对象发送一条delloc消息,一般会重写dealloc方法,在这里释放相关的资源,dealloc就向“临终遗言”一旦重写了dealloc方法 就必须调用[super dealloc],并且在代码块最后调用(不能直接调用)。

oc内存管理分类

object-c提供了三种内存管理方式:

Mannul Reference Counting        MRC     手动内存管理

automatoic reference counting    ARC     自动内存管理

garbage colletion(垃圾回收)          ios不支持垃圾回收

需理解MRC,但实际使用尽量用ARC

如何把arc











1 口诀。

1) 谁创建,谁释放。如果你通过alloc、new或copy来创建一个对象,那么你必须调用release或autorelease。换句话说,不是你创建的,就不用你去释放。

2) 除了alloc、new或copy之外的方法创建的对象都被声明了autorelease。

3) 谁retain,谁release。只要你调用了retain,无论这个对象是如何生成的,你都要调用release。有时候你的代码中明明没有retain,可是系统会在默认实现中加入retain。

注意:对象被释放后不能访问它的引用计数器,如果访问的话是野指针访问会造成系统崩溃。

3.重写dealloc方法

1).对象被销毁的时候,会默认调用dealloc方法

2).dealloc方法书写规范,要先释放自己的对象空间,在释放父类的空间

3).注意:dealloc方法不用手动去调用,系统会根据引用计数器的值自动调用

空指针,野指针,僵尸对象
空指针:没有任何东西的指针(存储的东西是nil, Nall0)
给空指针发送消息不会报错
野指针:指向僵尸对象(不可用内存)的指针,给野指针发送消息会报错
错误:EXC_BAD_ACCECC:访问一块坏的内存(已经被回收,已经不可用的内存)

@property参数

1) property的语法格式:

@property (参数1,参数2)类型名字;

这里的参数,主要有以下三种:

setter/getter方法(assign/retain/copy)

读写属性(readwrite/readonly)

atomicity(nonatomic)

三种使用方式

assign/retain/copy  代表赋值的方式。

readonly关键字代表setter不会被生成, 所以它不可以和 copy/retain/assign组合使用。

atomicity的默认值是atomic,读取函数为原子操作。

1.2.1 copy/reain/assign 在其中选择一个来确定属性的setter如何处理这个属性。NSObject对象采用这个中方式。

1.2.2 一些特别的Object比如NSSstring使用copy。

1.2.3 assign关键字代表setter直接赋值,而不是复制或者保留它。适用于基本数据类型,比如NSInteger和CGFloat,或者你并不直接拥有的类型,比如delegates。

set方法处理:

1).assign  直接赋值,适用于非oc对象,默认

   例:@property(nonatomic, assign) int   age;

2).retain  先release旧值,再retain新值

   例:@property (nonatomic, retain) NSString  *name;

3).copy分为浅复制和深复制   先release原来的值,再copy新值

4.set和get的方法名称,主要用于布尔类型。因为返回布尔类型的方法名一般以is开头,修改名称一般用在布尔类型中的getter。 

1).替换set方法的名称:@property (nonatomic, setter = isVip:)

                                            [p setVip:YES];  -------->[p isVip=YES];

2).替换get方法的名称:@property(nonatomic,getter=isVip:)

                                           [p isVIP:YES];

@class的使用

1.格式:@class   类名

2.@class XXX      含义:告诉编译器,XXX是一个类,至于类有哪些方法和属性,此处不去检查

                              好处:如果XXX文件内容发生改变,而不需要重写编译

3.@class使用注意:

1).    .h     @class   XX;

2).    .m    #import   "XX.h"

@class的特殊用法可以解决循环引用问题

4.#import   和@class的区别

#import会包含引用类的所有信息(内容),包括引用类的属性和方法

@class仅仅是告诉编译器有这么一个类,具体类里面有什么信息,完全不知道

效率上的区别

如果有上百个文件都#import了同一个文件或者这些文件依次被#import,那么一旦开始的头文件有改动,后面引用了这个头文件的类都要重新编译,编译效率非常低,使用@class就不会出现这种问题。

5.循环retain会导致两个对象都会内存泄漏
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: