OC學習篇之---循環引用問題 分類: IOS 2014-12-14 17:24 2184人閱讀 評論(0) 收藏

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

http://blog.csdn.net/jiangwei0910410003/article/details/41926183數組

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

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

來看一個具體的例子:spa

Dog類和Person類之間相互引用.net


Dog.hcode

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

#import <Foundation/Foundation.h>

#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 <Foundation/Foundation.h>

@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類型的屬性


看一下測試代碼blog

main.mip

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

#import <Foundation/Foundation.h>

#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方法中沒有被執行,裏面的釋放代碼也就沒執行了,dogperson各自在等待,造成環狀了


解決的辦法是:

切斷他們之間的聯繫

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

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

上面的例子中,咱們能夠看到Dog類中就是使用assgin


總結

循環引用是對象銷燬的時候遇到的最大的一個問題,在java中,垃圾回收器也會遇到這樣的問題,因此就不採用引用計數法去管理對象了,而是另外的一種方式去管理,能夠參考:http://blog.csdn.net/jiangwei0910410003/article/details/40709457

相關文章
相關標籤/搜索