程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> OC學習篇之---循環引用問題

OC學習篇之---循環引用問題

編輯:關於C語言

OC學習篇之---循環引用問題


在之前的一片文章中,我們介紹了數組操作對象的時候引用問題以及自動釋放池的概念:

 

今天我們繼續來看一下引用計數中一個痛疼的問題:循環引用

關於循環引用的問題,這裡就不做太多解釋了,就是多個對象之間相互引用,形成環狀。

來看一個具體的例子:

Dog類和Person類之間相互引用

 

Dog.h

 

//
//  Dog.h
//  29_CyclePointer
//
//  Created by jiangwei on 14-10-13.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import 

#import Person.h

@interface Dog : NSObject

//這裡不用retain,如果使用retain的話,會形成循環引用
@property(nonatomic,assign,readwrite) Person *person;

- (void)dealloc;

@end

 

 

Dog.m

 

//
//  Dog.m
//  29_CyclePointer
//
//  Created by jiangwei on 14-10-13.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import Dog.h

@implementation Dog

- (void)dealloc{
    //[_person release];
    NSLog(@dog dealloc);
    [super dealloc];
}

@end
Dog類中有一個Person類型的屬性

 

 

Person.h

 

//
//  Person.h
//  29_CyclePointer
//
//  Created by jiangwei on 14-10-13.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import 

@class Dog;

@interface Person : NSObject

@property(nonatomic,retain,readwrite) Dog *dog;

- (void)dealloc;

@end

Person.m

 

 

//
//  Person.m
//  29_CyclePointer
//
//  Created by jiangwei on 14-10-13.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import Person.h

#import Dog.h

@implementation Person

- (void)dealloc{
    [_dog release];
    NSLog(@Person dealloc);
    [super dealloc];
}

@end
Person類中有Dog類型的屬性

 

 

看一下測試代碼

main.m

 

//
//  main.m
//  29_CyclePointer
//
//  Created by jiangwei on 14-10-13.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import 

#import Dog.h
#import Person.h

//循環引用
//是一個很麻煩的一件事,完全靠經驗
int main(int argc, const char * argv[]) {
    
    Person *p = [[Person alloc] init];
    Dog *dog = [[Dog alloc] init];
    
    [p setDog:dog];//dog計數:2
    
    [dog setPerson:p];//person計數:2
    
    [p release]; //person計數:1
    [dog release];//dog計數:1
    
    //沒有釋放的原因是dealloc方法中沒有被執行,裡面的釋放代碼也就沒執行了,dog和person各自在等待,形成環狀了
    //解決版本就是切斷他們之間的聯系
    //@property中不使用retain,使用assgin
    
    NSLog(@is over);
    
    return 0;
}
我們分別定義了一個Person對象和Dog對象,然後相互引用了,但是當我們調用他們的release方法的時候,這兩個對象並沒有被釋放

 

原因很簡單:

 

person和dog的相互引用了,當執行release方法的時候引用計數都還是1,所以就不會調用dealloc方法了

dealloc方法中沒有被執行,裡面的釋放代碼也就沒執行了,dog和person各自在等待,形成環狀了

 

解決的辦法是:

 

切斷他們之間的聯系

在一方中定義屬性的時候,@property中不使用retain,使用assgin

同時在dealloc方法中不再調用release方法了

上面的例子中,我們可以看到Dog類中就是使用assgin

 

 





  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved