美文网首页
循环引用

循环引用

作者: 悟2023 | 来源:发表于2017-12-11 15:39 被阅读3次

1、循环引用对App的影响

内存无法释放 >> 性能降低 >> 闪退

2、循环引用具体存在情景(相互包含、block、delegate、NSTimer)

----(假如有ZQViewControllerZQObject对象)

  • 相互包含
//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(当前控制器对象).这里就出现了循环引用。

相关文章

  • 4-8 循环引用

    3种循环引用 自循环引用 相互循环引用 多循环引用 Block的循环引用 NSTimer 的循环引用 破除循环引用...

  • 循环引用的相关问题

    1、循环引用的种类(1)自循环引用(2)相互循环引用(3)多循环引用 如何破除循环引用?(1)避免产生循环引用(2...

  • iOS 内存管理面试题(循环引用)

    循环引用 循环引用的实质:多个对象相互之间有强引用,不能释放让系统回收。 如何解决循环引用? 1、避免产生循环引用...

  • 内存管理-循环引用

    三种类型循环引用 自循环引用 相互循环引用 多循环引用 自循环引用 假如有一个对象,内部强持有它的成员变量obj,...

  • iOS 循环引用

    1. 循环应用的分类: 自循环引用; 相互循环引用; 多循环引用; 自循环引用: 一个对象中有一个成员变量A; 如...

  • iOS开发 循环引用的几种场景

    delegate 循环引用如果delegate使用strong修饰容易引起循环引用 block 循环引用block...

  • Day2

    1 单方向的引用不会产生循环引用。循环引用:闭包引用了self,self引用了闭包。Swift推荐使用解决循环引用...

  • 避免Block的循环引用

    避免Block的循环引用 什么是循环引用,什么时候发生循环引用 1 循环引用就是当self 拥有一个block的...

  • iOS基础 Block解决循环引用

    block 循环引用循环引用 A对象持有B,B又持有A,互相强引用 解决循环引用问题:ARC 和MRC ARC:...

  • 2019-03-07 对WKWebView中的循环引用的理解

    WKWebView的这个循环引用很像定时器的循环引用。定时器的循环引用是因为系统runloop循环 强引用了执行...

网友评论

      本文标题:循环引用

      本文链接:https://www.haomeiwen.com/subject/rznbixtx.html