十一、内存管理中的循环引用
2015-03-15 10:21
267 查看
------ <a href="http://www.itheima.com" target="blank">Windows Phone 7手机开发</a>、<a href="http://www.itheima.com" target="blank">.Ios培训</a>、期待与您交流! -------
首先,我们得知道什么是循环引用。循环引用就是你中有我,我中有你。例如,有A类与B类两个类,A类中有B类型的成员变量,B类中有A类型的成员变量,然后通过调用相应的setter与getter方法,来实现的引用,叫做循环引用。
然后,我们需要知道循环引用有两种类型,一种是非ARC机制下的循环引用,一种是ARC机制下的循环引用。
一、非ARC机制下的循环引用(代码演示):
main函数:
House类的声明与实现:
Window类的声明与实现:
程序运行结果为:不显示任何东西。
程序运行这样的结果的原因,程序在执行完后,_house以及_window这两个oc类型的成员变量,都有强指针指向,因为对象不会被回收,系统也就不会调用-dealloc方法。
我们需要将House类声明与Window类声明中@property参数中的一端改为assign,一端保持retain不变,然后在House类的.m文件中的头文件中添加#import Window.h,同样的,在Window类的.m 文件中的头文件中添加#import House.h。最后还需要在House类的-dealloc方法中释放掉_window对象,[_window
release],同样的,在Window类的-dealloc方法中释放掉_house对象。
改后程序运行结果如下:
修改后的代码,符合苹果官方的内存管理机制,“谁alloc,就谁release,一个alloc对应一个release”。
下面来看看,如何使用苹果官方的ARC机制,将非ARC代码转换成ARC代码。
1.选择xcode上端工具栏里面的Edit,选择Edit里面的Refactor,再选择Convert Object-C ARC,勾选需要转换的项目。
2.点击check,然后点击next,会出现预览,就说是ARC代码与非ARC代码的预览
3.最后点击save,选择enable,即可将非ARC代码转换成ARC代码。
注意:转换成ARC代码后,将无法转会成非ARC代码,若需要保留非ARC代码,应该先备份一份非ARC代码。
总结:
ARC代码与非ARC代码总体来的区别就是不需要用户调用release或者是autorelease来进行内存空间的释放,系统会自动释放内存空间。同时在ARC代码中,所有的@property中的oc对象中的retain全部变为strong,oc对象中的的assign全部变为weak。strong
代表强指针,一般用户默认创建的指针都为强指针,有强指针指向的对象不会被回收,weak代表弱指针,在需要创建的指针前面写上__weak则代表该指针为弱指针,若一个对象没有被强指针指向,只有被弱指针指向,那么这个对象会被回收。还有,ARC代码中的-dealloc方法里面,不再允许这样调用[super
dealloc]。注意:并不是所有项目都可以使用ARC机制,某些第3方框架,不支持ARC机制,这时我们需要关闭部分文件的ARC机制。我们在Build Phases 里面选择comple source,然后再相应的.m文件后,输入-fno-objc-arc,这样即可关闭某个文件的ARC机制。同样,我们可以输入-f-objc-arc来打开某个文件的ARC机制。
首先,我们得知道什么是循环引用。循环引用就是你中有我,我中有你。例如,有A类与B类两个类,A类中有B类型的成员变量,B类中有A类型的成员变量,然后通过调用相应的setter与getter方法,来实现的引用,叫做循环引用。
然后,我们需要知道循环引用有两种类型,一种是非ARC机制下的循环引用,一种是ARC机制下的循环引用。
一、非ARC机制下的循环引用(代码演示):
main函数:
#import <Foundation/Foundation.h> #import "House.h" #import "Window.h" int main() { House *h = [[House alloc] init]; Window *w = [[Window alloc] init]; h.num = 110; w.size = 19.9; // 下面两句为循环引用的关键语句: h.window = w; w.house = h; // 在非ARC机制下,有alloc就必须有release,并且谁alloc就必须谁release [w release]; [h release]; return 0; }
House类的声明与实现:
#import <Foundation/Foundation.h> // @class关键字的作用,是告诉编译器,某个名称是一个类 // 此处的@class是告诉编译器,Window是该文件中的一个类 // 并且@class是写在类的声明里面 @class Window; // 注意@class中的c不要写成大写的C,oc中的关键字是区分大小写的!!! @interface House : NSObject @property (nonatomic,retain) Window *window; @property (nonatomic,assign) int num; @end
#import "House.h" @implementation House - (void)dealloc // 当House类的对象被回收时,系统自动调用- dealloc方法 { NSLog(@"房屋号码为%d的House对象内存被回收",[self num]); // 打印用于检测House对象是否被回收 [super dealloc]; // 在非ARC机制下,用户重写- dealloc方法时,必须在该方法最后加上[super dealloc] } @end
Window类的声明与实现:
#import <Foundation/Foundation.h> @class House; @interface Window : NSObject @property (nonatomic,retain) House *house; // Window类中的有House类型的成员变量,该变量是oc对象 @property (nonatomic,assign) double size; @end
#import "Window.h" @implementation Window - (void)dealloc // 当Window类的对象被回收时,系统自动调用- dealloc方法 { NSLog(@"尺寸为%.2f的Window对象内存被回收",[self size]); // 打印用于检测Window对象是否被回收 [super dealloc]; // 在非ARC机制下,用户重写- dealloc方法时,必须在该方法最后加上[super dealloc] } @end
程序运行结果为:不显示任何东西。
程序运行这样的结果的原因,程序在执行完后,_house以及_window这两个oc类型的成员变量,都有强指针指向,因为对象不会被回收,系统也就不会调用-dealloc方法。
我们需要将House类声明与Window类声明中@property参数中的一端改为assign,一端保持retain不变,然后在House类的.m文件中的头文件中添加#import Window.h,同样的,在Window类的.m 文件中的头文件中添加#import House.h。最后还需要在House类的-dealloc方法中释放掉_window对象,[_window
release],同样的,在Window类的-dealloc方法中释放掉_house对象。
改后程序运行结果如下:
修改后的代码,符合苹果官方的内存管理机制,“谁alloc,就谁release,一个alloc对应一个release”。
下面来看看,如何使用苹果官方的ARC机制,将非ARC代码转换成ARC代码。
1.选择xcode上端工具栏里面的Edit,选择Edit里面的Refactor,再选择Convert Object-C ARC,勾选需要转换的项目。
2.点击check,然后点击next,会出现预览,就说是ARC代码与非ARC代码的预览
3.最后点击save,选择enable,即可将非ARC代码转换成ARC代码。
注意:转换成ARC代码后,将无法转会成非ARC代码,若需要保留非ARC代码,应该先备份一份非ARC代码。
总结:
ARC代码与非ARC代码总体来的区别就是不需要用户调用release或者是autorelease来进行内存空间的释放,系统会自动释放内存空间。同时在ARC代码中,所有的@property中的oc对象中的retain全部变为strong,oc对象中的的assign全部变为weak。strong
代表强指针,一般用户默认创建的指针都为强指针,有强指针指向的对象不会被回收,weak代表弱指针,在需要创建的指针前面写上__weak则代表该指针为弱指针,若一个对象没有被强指针指向,只有被弱指针指向,那么这个对象会被回收。还有,ARC代码中的-dealloc方法里面,不再允许这样调用[super
dealloc]。注意:并不是所有项目都可以使用ARC机制,某些第3方框架,不支持ARC机制,这时我们需要关闭部分文件的ARC机制。我们在Build Phases 里面选择comple source,然后再相应的.m文件后,输入-fno-objc-arc,这样即可关闭某个文件的ARC机制。同样,我们可以输入-f-objc-arc来打开某个文件的ARC机制。
相关文章推荐
- Objective-C(十五、内存管理,MRC,循环引用,dealloc和setter方法)——iOS开发基础
- Objective-C—引用计数器、多个对象之间的内存管理、set方法的内存管理、@property参数、循环引用
- 黑马视频学习笔记-内存管理-循环引用
- 黑马程序员-内存管理之set方法内存管理, property参数,循环引用。
- Objective-C基础学习笔记(八)-内存管理-autorelease使用-property创建对象的内存管理-循环引用的内管管理
- 黑马程序员--IOS_内存管理_@class和循环引用的问题。
- OC内存管理-ARC-循环引用
- 内存管理--循环引用
- iOS内存管理(4)--Block属性用copy修饰 & 避免循环引用的问题
- 黑马程序员24——OC之内存管理(循环引用)
- 【Objective-C高级编程】iOS与OS X多线程和内存管理(九) Block 循环引用
- iOS内存管理之循环引用
- IOS内存管理的经典问题(循环引用)
- iPhone开发资料之内存管理 ,循环引用导致的内存问题
- objective-c启用ARC时的内存管理 (循环引用)
- 黑马程序员---06@property内存管理中如何避免循环引用的问题
- Swift:(十一)、构造器、自动引用计数、循环引用问题解决、类型转换
- OC基础—内存管理之@property及其参数(补充新知识:循环引用和@class)
- Swift 内存管理与循环引用问题(weak、unowned)