1、循环引用对App的影响
内存无法释放
>> 性能降低
>> 闪退
2、循环引用具体存在情景(相互包含、block、delegate、NSTimer)
----(假如有ZQViewController
、ZQObject
对象)
- 相互包含
//ZQViewController.m中是如下Code
@interface ZQViewController ()
@property (nonatomic,strong) ZQObject * object;
@end
@implementation ZQViewController
- (void)dealloc {
NSLog(@"循环引用该方法不会执行");
}
- (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(@"循环引用该方法不会执行");
}
- (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
,此时就出现了相互强引用,这个时候由于二者的RetainCount不可能为0,所以导致对象无法释放。
- delegate
#import "ZQViewController.h"
#import "ZQObject.h"
@interface ZQViewController ()
<ObjectDelegate>
@property (nonatomic,strong) ZQObject * object;
@end
@implementation ZQViewController
- (void)dealloc {
NSLog(@"循环引用该方法不会执行");
}
- (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)对象,等到自身失效才释放。执行完任务后,一次性的定时器会自动失效;重复性的定时器,需要主动调用invalidate方法才会失效。
创建定时器时,当前控制器引用而定时器了,在给定时器添加任务时,定时器保留了self(当前控制器对象).这里就出现了循环引用。
网友评论