Android應用安全防護和逆向分析-----作者
阿新 • • 發佈:2019-01-07
在之前的一片文章中,我們介紹了陣列操作物件的時候引用問題以及自動釋放池的概念:
今天我們繼續來看一下引用計數中一個痛疼的問題:迴圈引用
關於迴圈引用的問題,這裡就不做太多解釋了,就是多個物件之間相互引用,形成環狀。
來看一個具體的例子:
Dog類和Person類之間相互引用
Dog.h
Dog.m// // 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
// 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型別的屬性看一下測試程式碼
main.m
//
// 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方法中沒有被執行,裡面的釋放程式碼也就沒執行了,dog和person各自在等待,形成環狀了
解決的辦法是:
切斷他們之間的聯絡
在一方中定義屬性的時候,@property中不使用retain,使用assgin
同時在dealloc方法中不再呼叫release方法了
上面的例子中,我們可以看到Dog類中就是使用assgin
總結