oc内存管理

=======================

内存管理

=======================


静态内存区


自动变量 类似 auto int a 


动态内存区(堆区)


[] 堆空间需要程序员手动分配内存, 使用完堆内存,手动释放内存, 保证堆内存正确释放(使用完才释放,肯定会释放,保证只释放一次),这就是c的内存管理.


[内存管理]

[c的内存管理--存在的问题]

<1>.提前对一个正在使用的堆内存 进行释放操作,导致数据不安全,称为[提前释放]

<2>不对自己开辟的堆内存进行释放操作, 导致内存无法及时回收,称为[内存泄露]

<3>对一个已经释放的堆内存,再一次做释放操作,导致程序崩溃,称为[重复释放]

[c的内存管理-困境]

<1>多个指针指向同一个堆内存,必须保证所有指针使用完堆内存才能释放.避免[提前释放].

<2>多个指针指向同一个堆内存,必须保证最后一个使用对堆内存的指针进行释放.避免[重复释放].

<3>在多模块(函数)协同开发中,无法知晓哪个模块是最后使用堆内存的模块.

<4>在多线程程序开发中,无法确定哪个线程最后结束.


oc语言中为了解决以上问题/困境,提出了 引用计数(reference count) 的概念.


oc中的指针 往往也称为 引用.


[引用计数的原理]


oc引用计数的原理类似于qq讨论组.


多一个指针指向一个对象,每个指针都会让对象的引用计数加1,一个指针不再指向(使用完毕) 对象的引用计数减1,当对象的引用计数减到0时,对象的内存被释放. 


oc中每个类都是NSObject的子类,使用类创建出来的对象都内置一个 引用计数(retainCount) . 


那么,oc的内存管理 就是 维护对象的引用计数正确加1/减1. 保证对象可以被正确释放.


oc中的内存管理分: 手动内存管理(MRC), 自动内存管理(ARC)


Manual Reference Counting(MRC)

Automatic Reference Counting(ARC)


[手动内存管理]


[] 进行手动内存管理,需要先关闭自动内存管理.


操作: [点击工程] => Targets => Build Settings => 搜索 gar  

Objective-C Automatic Reference Counting 改为 NO


Dog * dog = [[Dog alloc] init];

//alloc 使得 创建的对象引用计数为1


Dog * dog2 = [dog retain];//2

//retaindog对象的引用计数加1,并返回原对象的地址.


//dog2使用完毕,让对象的引用计数减1

[dog2 release];//2==>1


dog.retainCount //retainCount(引用计数/保留计数


[] retain 负责引用计数加1

release负责引用计数减1

retainCount 负责获取引用计数的值


- (id)retain OBJC_ARC_UNAVAILABLE;

- (oneway void)release OBJC_ARC_UNAVAILABLE;

- (id)autorelease OBJC_ARC_UNAVAILABLE;

- (NSUInteger)retainCount OBJC_ARC_UNAVAILABLE;


[oc内存管理的原则(法则)]


<1>凡是用alloc , retain ,new(new开头),copy(copy开头),mutableCopy(mutableCopy开头)的方法 "创建" 的对象,必须用release/autorelease 进行释放.


<2>谁创建,谁释放. alloc ,谁 release .


[传统的内存管理]


指针指向对象,retain ,指针不再指向对象,release.


[特殊情况下的内存管理]


析构方法在对象销毁前会被自动调用,用来对成员指针进行释放.


<1>对象的成员是 对象指针. 这个成员需要在析构方法中释放.

<2>发生指针的转移时, 需要release 旧对象,retain新对象.

<3>从数据结构中取出对象,如果想要长时间使用对象,必须retain


[] 这里说的数据结构包括(数组,字典),往数据结构中放入对象时默认进行了retain .

[] 数据结构本身销毁时,会对数据结构中所有对象发送release消息.

【autorelease自动释放池原理】

手动内存管理提供了一个自动释放机制,称为自动释放池

当一个对象不再使用时可以直接将对像放入自动释放池中,并不是直接调用relaease方法释放对象,当池销毁时,池中的所有对象都会发送release消息。

将一个对象放入自动释放池是通过autorelease实现的

autorelease并不是直接让对象引用计数减一,而是直接将对象放入自动释放池中。

iOS引用程序中,每隔一段时间自动销毁并产生一个自动释放池。

【autorelease的应用场景】

在一个函数内,局部使用的对象,使用完毕时。可以直接使用autorelease。 

类方法返回一个对象时,一般都用autorelease进行释放。

【注】自动释放池的销毁并不会打断一个函数的调用

【注】不能用iOS程序中的类方法创建一个长时间使用的对象。

【属性修饰符-内存管理】

retain ,应用计数加1

//Xcode5以后新镇的修饰符

strong,strong在arc中作为对象成员的修饰符

                strong修饰的指针,指针指向一个对象,对象的引用计数加1,当指向的对象销毁时,指针会发送release消息。

weak,weak修饰的指针,指向一个对象不会retain,当指向的对象销毁时,指针会自动变为nil。

unsafe-unretain 修饰的指针,指向一个对象,不会retain,当指向的对象被销毁指针也不会变为nil。

copy.字符串,block变量使用copy

weak,代理对象/ui控件使用weak。对象使用出现了循环应用。

strong,一般对象指针(除了字符串)使用strong。

【引用修饰符】

-strong修饰的指针,指针指向一个对象,对象的引用计数加1,当指向的对象销毁时,指针会发送release消息。

【copy、mutableCopy区别】

【对象 copy】

【对象 mutableCopy】

对于不可变对象,copy只是拷贝了对象的地址,mutablecopy才是拷贝了一个新的对象,对于可变对象,copy,mutablecopy都是拷贝了一个新的对象

【注】对于自定义类的对象,不是随便都可以使用copy,mutable copy来拷贝一个新对象,自定义类必须遵从nscopy或者nsmutablecoping协议。并且实现协议中的copyWithzone:/mutablecopyzone:方法,这样才可以实现对自定义对象的拷贝

对于不可变对象,copy是浅拷贝,mutable copy是深拷贝

对于可变对象,copy,mutable copy都是深拷贝。

//实现构造方法,会被自动调用.

-(void)dealloc

{

    //成员指针 release

    //[_title release];

    self.title = nil;

    self.url = nil;

    [super dealloc];

}

-(void)setTitle:(NSString *)title

{

    //防止成员指针的[自赋值]

    if(_title != title)

    {

        [_title release];//release旧对象

        _title = [title retain];//retain新对象

    }

}


[new , copy, mutableCopy]


使用new创建对象时,内部自动调用alloc,init . 


[dog copy];  // 创建不可变对象

[dog mutableCopy] ;// 创建可变对象


[自动内存管理]


程序员不需要手动写代码(retain,release等)来实现内存管理. 程序在预处理期会在代码中最合适的地方添加 retain,release 等语句.


从Xcode5开始,所创建的工程默认都是基于ARC的.


oc的自动内存管理不同于 java的垃圾回收机制.


.[ARC下的工程所产生的问题]

<1>由于代码的书写不规范,导致对象被释放

比如后期使用 AVAudioPlayer时,最有可能出现这个问题.


  <2>向程序中导入 一些官方库/第三方代码/旧代码 时, 如果这些代码是用MRC环境编写的(内部有大量的retain,release语句). 直接导入工程会导致整个工程无法编译.  


.[解决ARC环境下无法编译MRC代码问题]

<1>先让整个工程处于MRC环境下. 然后使用转换工具将MRC代码转为 ARC代码.

操作步骤: Edit => Refactor => Convert to Objective-C ARC ...

d

<2>MRCARC混编

MRC代码单独用MRC环境编译,其他代码依然用ARC环境编译.

根据以下步骤,找出指定的文件,添加编译选项(标签) -fno-objc-arc

步骤: [点击工程]=>Targets=>Build Phases=>Compiler Sources


[] 实际是ARC的执行效率比MRC.





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值