iOS循環引用問題

平常我們常見的循環引用有block循環引用和對象之間相互強引用兩種情況;

1、block循環引用問題:例如

#import "Person.h"

typedef void(^PersonBlock)(NSString *name);

@interface Person()

@property (nonatomic,strong)NSArray *propertyS;

@property (nonatomic,strong)PersonBlock block;

@end

@implementation Person

- (id)init

{

    if (self = [super init]) {

        self.propertyS = @[@"", @"23"];

        self.block = ^(NSString *name){

            NSLog(@"arr:%@", self.propertyS);

        };

    }

    return  self;

}

@end

其中在block中調用propertyS會有警告出現,這是因爲在block中調用了self所擁有的東西,引起了循環引用,那麼這個循環引用具體怎樣引起的呢?
(1)block中引用了self,self被block retain,propertyS又retain了該block的一個拷貝
(2)propertyS是在self中定義賦值的,因此是被self retain的
因此形成了循環引用,不會調用dealloc
解決方法是利用__weak或者__unsafe__unretained去修飾self(在ARC模式下),在MRC模式下用__block修飾


2、兩個對象之間相互強引用:

@interface Person : NSObject

{

    Person  *person1;

    Person  *person2;

    NSArray *array;

}

@property (readwrite,assign)Person *person1;

@property (readonly)Person *person2;


@end

person擁有兩個Person對象,每個對象又都擁有一個NSArray對象。屬性person1和person2都指向了彼此的Person對象。那麼兩個對象間形成了強引用,ARC將不會銷燬這個對象。
爲了阻止這種事的發生,聲明其中一個屬性爲弱引用即可(__weak Person *person2)。這樣,當person2指向空並且Person對象超出範圍時,ARC可以安全的給這個對象發送一個release消息。

__weak指示符既可以聲明弱引用,也可以聲明空引用。__unsafe_unretained聲明弱引用,不是空引用。如果要用後者,那麼要自己處理空引用,否則會內存泄漏


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章