美文网首页
关于单例、block和dispatch_after的笔记

关于单例、block和dispatch_after的笔记

作者: 大成小栈 | 来源:发表于2021-08-09 21:10 被阅读0次
    1. 单例的指针被静态存储器的静态变量引用着,单例不能释放,直到程序退出或者杀死后,内存才能被释放。那么,怎样中途释放单例呢?
    2. dispatch_after和performSelector:afterDelay:会引起强引用self,并导致循环引用吗?
    3. 在单例中强引用的block,其中的self会强引用该单例吗?

    测试以下代码,可解相关疑惑:

    //// .h
    #import <Foundation/Foundation.h>
    
    @interface TestInstance : NSObject
    
    + (instancetype)sharedInstance;
    + (void)attempDealloc;
    - (void)testDisptchAfter;
    - (void)test;
    
    @end
    
    
    //// .m
    #import "TestInstance.h"
    
    typedef void(^TestBlock)(NSInteger value);
    
    @interface TestInstance ()
    
    @property (nonatomic, copy)TestBlock testBlock;
    @property (nonatomic, strong)NSString *testTitle;
    
    @end
    
    static TestInstance *manager = nil;
    static dispatch_once_t onceToken;
    
    @implementation TestInstance
    
    + (instancetype)sharedInstance {
        
        dispatch_once(&onceToken, ^{
            manager = [[TestInstance alloc] init];
            
            
        });
        return manager;
    }
    
    - (void)testDisptchAfter {
        
    //    [self performSelector:@selector(haha) withObject:nil afterDelay:1.0];
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    
            self.testTitle =  @"testDisptchAfter";
    
        });
    }
    
    - (void)haha {
        
        self.testTitle =  @"haha";
    }
    
    - (void)test{
        
        __weak typeof(self)weakSelf = self;
        _testBlock = ^(NSInteger value) {
            weakSelf.testTitle = [NSString stringWithFormat:@"%d", value];
    //        self.testTitle = [NSString stringWithFormat:@"%d", value];
        };
        _testBlock(5);
    }
    
    - (void)dealloc
    {
        NSLog(@"dealloc------>>");
    }
    
    + (void)attempDealloc {
    //    onceToken = 0; // 只有置成0,GCD才会认为它从未执行过.它默认为0,这样才能保证下次再次调用shareInstance的时候,再次创建对象.
        manager = nil;
    }
    
    @end
    

    答案:

    1. 只有全局的onceToken置成0,系统才能释放manager;才能保证下次再次调用shareInstance的时候,再次创建对象。
      onceToken = 0;
      manager = nil;
    2. dispatch_after和performSelector:afterDelay:不会引起强引用self。
    3. 单例中block会强引用self。但是,一般单例是不随便释放的,若不强制释放,其dealloc不管是否有block的存在,都不会走。

    相关文章

      网友评论

          本文标题:关于单例、block和dispatch_after的笔记

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