对象之间的循环引用 两个对象A、B,有可能会出现一种特殊的情况:A中包含B的实例变量;B中又包含A的实例变量,如果两个实例变量都是强引用(A有B实例变量的所有权,B也有A的实例变量的所有权),然后再两个对象销毁时,会出现A、B都不能正常销毁的情况。 类A:
// A.h
// 02-循环引用
//
// Created by ma c on 15/8/14.
// Copyright (c) 2015年. All rights reserved.
//
#import <Foundation/Foundation.h>
//类的前向声明(只存在包含关系中)
@class B;
@interface A : NSObject
@property(nonatomic,retain)B *b;//A获得b对象的所有权
@end
-------------------------------------------------------
// A.m
// 02-循环引用
//
// Created by ma c on 15/8/14.
// Copyright (c) 2015年. All rights reserved.
//
#import "A.h"
#import "B.h"
@implementation A
-(void)dealloc
{
[_b release];
NSLog(@"A dealloc");
[super dealloc];
}
@end
类B:
// B.h
// 02-循环引用
//
// Created by ma c on 15/8/14.
// Copyright (c) 2015年. All rights reserved.
//
#import <Foundation/Foundation.h>
@class A;
@interface B : NSObject
@property(nonatomic,retain)A *a;//B获得a对象所有权
@end
------------------------------------------------------------
// B.m
// 02-循环引用
//
// Created by ma c on 15/8/14.
// Copyright (c) 2015年. All rights reserved.
//
#import "B.h"
#import "A.h"
@implementation B
-(void)dealloc
{
//[_a release];
NSLog(@"B dealloc");
[super dealloc];
}
@end
主函数测试:
1 // main.m
2 // 02-循环引用
3 //
4 // Created by ma c on 15/8/14.
5 // Copyright (c) 2015年. All rights reserved.
6 //
7
8 #import <Foundation/Foundation.h>
9 #import "A.h"
10 #import "B.h"
11 int main(int argc, const char * argv[])
12 {
13 @autoreleasepool
14 {
15 //测试对象间的循环引用
16 A *a = [[A alloc]init];
17 B *b = [[B alloc]init];
18
19 [a setB:b];
20 [b setA:a];
21
22 [a release];
23 [b release];
24
25 }
26 return 0;
27 }
测试结果是:
Program ended with exit code: 0
上面的结果明显的a和b对象都没有成功释放内存而销毁,因为它们都是retain获得对方的所有权,谁都不肯先释放;
处理方法:将双方任意一方的对象属性retain做一下修改即可,改为assign
修改后测试结果如下:
2015-08-14 16:32:27.210 02-循环引用[1427:94559] A dealloc
2015-08-14 16:32:27.211 02-循环引用[1427:94559] B dealloc
Program ended with exit code: 0
转载于:https://www.cnblogs.com/XYQ-208910/p/4730431.html