- 单例的指针被静态存储器的静态变量引用着,单例不能释放,直到程序退出或者杀死后,内存才能被释放。那么,怎样中途释放单例呢?
- dispatch_after和performSelector:afterDelay:会引起强引用self,并导致循环引用吗?
- 在单例中强引用的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
答案:
- 只有全局的onceToken置成0,系统才能释放manager;才能保证下次再次调用shareInstance的时候,再次创建对象。
onceToken = 0;
manager = nil;- dispatch_after和performSelector:afterDelay:不会引起强引用self。
- 单例中block会强引用self。但是,一般单例是不随便释放的,若不强制释放,其dealloc不管是否有block的存在,都不会走。
网友评论