您的位置:首页 > 其它

第十一篇:OC中类的互引用问题及解决方法

2015-09-12 14:54 309 查看
1.类的头文件互引用:

》表现:在两个类A,B的声明中,A.h文件中导入了B.h,并且B.h文件中导入了A.h。

A.h文件中:

#import <Foundation/Foundation.h>

#import "B.h"

@interface A : NSObject ......... @end

B.h文件中:

#import <Foundation/Foundation.h>

#import "A.h"

@interface B : NSObject ......... @end

》问题:这样就会出一个无限循环的拷呗状态。无法编译成功。

2.解决类的头文件互引用方法:

》用关键字:@class 类名。

》关键字说明:在编译时,告诉编译器有一个类叫 “类名”。

》用法:在两个类A,B的声明中,A.h文件中换成@class B,并A.m文件中导入B.h;也可在B.h文件中换成@class A,并在B.m文件中导入A.h,只要不形成 无限循环的拷呗状态 即可。

A.h文件中:

#import <Foundation/Foundation.h>

@class B;

@interface A : NSObject ......... @end

B.h文件中:

#import <Foundation/Foundation.h>

@class A;

@interface B : NSObject ......... @end

》优点:即可以解决无限循环的拷呗状态,也可以减少编译的时间。因为在编译的时候 导入.h文件也就是一个拷呗的过程。

3.成员变量的 手动管理对象引用计数器(MRC) 被循环判断且循环执行dealloc对象方法 和 内存泄漏问题:

》前提:两个类A和B,A类中有类型为B的成员变量 _b,B类中有类型为A的成员变量 _a

》A类的成员变量 _b 的set / get 方法:@property (nonatomic ,retain)B * b ;

B类的成员变量 _a 的set / get 方法:@property (nonatomic ,retain)A * a ;

实现了dealloc对象方法:- (void) dealloc{ [ name release] ; [surper dealloc] ; } //name = _a 或 _b

》main函数体如下:

A * pa = [ [A alloc] init ] ; // pa引用计数 = 1

B * pb = [ [B alloc] init ] ; // pb引用计数 = 1

[pa setB: pb] ; // pb引用计数 = 2

[pb setA: pa] ; // pa引用计数 = 2

// 一个alloc 对应一个 release

[pb release] ; // pb引用计数 = 1

[pa release] ; // pa引用计数 = 1

(1)问题:

》上面main函数体的代码出现内存泄漏:

两个对象引用计数 都等于1,在堆里面开辟的空间没有清空。两个对象都没有调用dealloc对象方法。

》如果上面的[pb setA: pa]; 这行代码去掉,那么会在[pa release] ; 这行代码, pa引用计数 = 0 ,会无限循环调用A类dealloc,B类dealloc , _a是个野指针,出现报错。

(2)解决方案:

》两个类中set方法管理内存,一个用retain , 一个用assign。

》在两类中做如下更改: 在A类:@property (nonatomic ,retain)B * b ;

在B类:@property (nonatomic ,assign)A * a ;

4.自动管理内存(ARC)的互引用:

》问题:strong 对象的指针 出现了循环互引用。这样就会导致在一个相互指向的循环圈内的对象内存不能被释放,出现内存泄漏问题。

》解决:一端用strong 类型指针,一端用weak类型指针。只要没有出现 强指针类型的对象 循环指向就可以解决该问题。

5.总结:

》对于头文件互引用问题,解决方法:在头文件中用@class 类名 ; 告诉编译器有那么一个类。

》对于对象出现的互引用问题,解决方法:

> ARC:一端用strong 类型指针,一端用weak类型指针。

> MRC :一端用 retain 类型指针,一端用 assign 类型指针。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: