1薄料、循環(huán)引用對App的影響
內存無法釋放
>> 性能降低
>> 閃退
2、循環(huán)引用具體存在情景(相互包含泵琳、block摄职、delegate、NSTimer)
----(假如有ZQViewController
获列、ZQObject
對象)
- 相互包含
//ZQViewController.m中是如下Code
@interface ZQViewController ()
@property (nonatomic,strong) ZQObject * object;
@end
@implementation ZQViewController
- (void)dealloc {
NSLog(@"循環(huán)引用該方法不會執(zhí)行");
}
- (void)viewDidLoad {
[super viewDidLoad];
self.object = [[ZQObject alloc] init];
_object.viewController = self;
}
//ZQObject.h中是如下Code
#import <Foundation/Foundation.h>
@interface ZQObject : NSObject
@property (nonatomic,strong) UIViewController * viewController;
@end
在如上Code情況中:
ZQViewController
強引用了ZQObject
谷市;同時ZQObject
強引用了ZQViewController
;這個時候由于二者的RetainCount不可能為0击孩,所以導致對象無法釋放迫悠。
注:CFGetRetainCount((__bridge CFTypeRef)(_object))
- block
#import "ZQViewController.h"
#import "ZQObject.h"
@interface ZQViewController ()
@property (nonatomic,strong) ZQObject * object;
@end
@implementation ZQViewController
- (void)dealloc {
NSLog(@"循環(huán)引用該方法不會執(zhí)行");
}
- (void)viewDidLoad {
[super viewDidLoad];
//情況一:
self.object = [[ZQObject alloc] init];
self.object.testBlock = ^{
[self doSomething];
};
//情況二:
self.object = [[ZQObject alloc] init];
__weak typeof(self) weakSelf = self;
self.object.testBlock = ^{
__strong typeof (weakSelf) strongSelf = weakSelf;
[strongSelf doSomething];
};
}
- (void)doSomething {
NSLog(@"做一些事情");
}
#import <Foundation/Foundation.h>
typedef void (^testBlock)(void);
@interface ZQObject : NSObject
@property (nonatomic, copy) testBlock testBlock;
@end
在如上Code情況中:
block在copy時都會對block內部用到的對象(self)進行強引用的。
ZQObject
中的block的方法體里面又使用了ZQViewController
巩梢,此時就出現(xiàn)了相互強引用创泄,這個時候由于二者的RetainCount不可能為0,所以導致對象無法釋放括蝠。
- delegate
#import "ZQViewController.h"
#import "ZQObject.h"
@interface ZQViewController ()
<ObjectDelegate>
@property (nonatomic,strong) ZQObject * object;
@end
@implementation ZQViewController
- (void)dealloc {
NSLog(@"循環(huán)引用該方法不會執(zhí)行");
}
- (void)viewDidLoad {
[super viewDidLoad];
self.object = [[ZQObject alloc] init];
_object.delegate = self;
}
#import <Foundation/Foundation.h>
@protocol ObjectDelegate <NSObject>
@end
@interface ZQObject : NSObject
@property (nonatomic, weak) id <ObjectDelegate> delegate;
@end
ZQViewController
持有ZQObject
對象鞠抑,同時_object.delegate = self;
ZQObject 持有
ZQViewController```對象,delegate如果也是strong類型引用忌警,二者的RetainCount不可能為0搁拙,所以導致對象無法釋放。
-
NSTimer
NSTimer 因為是比較特殊的情況法绵,所以很容易被我們忽略箕速。
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti
target:(id)aTarget
selector:(SEL)aSelector
userInfo:(nullable id)userInfo
repeats:(BOOL)yesOrNo;
方法的最后一個參數(repeats)為YES時,NSTimer會保留目標(target)對象,等到自身失效才釋放。執(zhí)行完任務后礼烈,一次性的定時器會自動失效弧满;重復性的定時器,需要主動調用invalidate方法才會失效。
創(chuàng)建定時器時,當前控制器引用而定時器了此熬,在給定時器添加任務時庭呜,定時器保留了self(當前控制器對象).這里就出現(xiàn)了循環(huán)引用。