zoukankan      html  css  js  c++  java
  • Objective-C:对象之间循环引用会造成死循环

    对象之间的循环引用
           两个对象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
  • 相关阅读:
    Python cmd库的简易使用
    声明式编程与命令式编程
    javascript移除树形列表(带children的对象数组)中的元素
    javascript将树结构的列表转换为普通列表(不带children)
    javascript将普通列表转换为树结构的列表(带children)
    webservice的概述
    java程序员面试应该具备的一些基本技能
    mysql生成随机id
    struts2的优点
    javascript常用的正则表达式集合
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/4730431.html
Copyright © 2011-2022 走看看