/*!
* @function dispatch_once
*
* @abstract
* Execute a block once and only once.
*
* @param predicate
* A pointer to a dispatch_once_t that is used to test whether the block has
* completed or not.
*
* @param block
* The block to execute once.
*
* @discussion
* Always call dispatch_once() before using or testing any variables that are
* initialized by the block.
*/
typedef long dispatch_once_t;
void
dispatch_once(dispatch_once_t *predicate,
DISPATCH_NOESCAPE dispatch_block_t block);
場景:項目中唯一的,且需要全局訪問的對象,我們使用單例啰脚。
#import <Foundation/Foundation.h>
@interface User : NSObject
@property (nonatomic, strong) NSString *job;
+ (User *)sharedInstance;
@end
#import "User.h"
static dispatch_once_t user_onceToken;
@implementation User
+ (User *)sharedInstance {
static User *user = nil;
dispatch_once(&user_onceToken, ^{
user = [[User alloc]init];
});
return user;
}
@end
[User sharedInstance].job = @"iOS developer";
NSLog(@"%@====%@",[User sharedInstance],[User sharedInstance].job);//<User: 0x600000018450>====iOS developer
場景:項目中,在退出時谱轨,需要把單例數(shù)據(jù)清空,該怎么做 吠谢?土童?
先簡單的把單例對象設(shè)置 user = nil; 然而根本沒用。
單例的數(shù)據(jù)實際上是 static User *user 這個靜態(tài)變量保存著工坊。
方案一:直接把單例的所有屬性一一清空數(shù)據(jù)献汗。
方案二:單例重新初始化,通過代碼控制dispatch_once的block王污。(我以前一直誤以為是不是dispatch_once_t *predicate罢吃,這個指針初始為空,執(zhí)行一次后非空昭齐,這樣子控制block是否執(zhí)行尿招。)
#import "User.h"
static dispatch_once_t user_onceToken;
@implementation User
+ (User *)sharedInstance {
static User *user = nil;
NSLog(@"before: %ld--%p",user_onceToken, &user_onceToken);
dispatch_once(&user_onceToken, ^{
NSLog(@"after: %ld--%p",user_onceToken, &user_onceToken);
user = [[User alloc]init];
});
return user;
}
@end
調(diào)用單例的代碼
[User sharedInstance].job = @"iOS developer";
NSLog(@"%@====%@",[User sharedInstance],[User sharedInstance].job);
輸出結(jié)果
2018-12-02 07:37:09.284862+0800 dispatch_once_t-Demo[51477:2436486] before: 0--0x1001100f8
2018-12-02 07:37:09.285004+0800 dispatch_once_t-Demo[51477:2436486] after: 768--0x1001100f8
2018-12-02 07:37:09.285141+0800 dispatch_once_t-Demo[51477:2436486] before: -1--0x1001100f8
2018-12-02 07:37:09.285246+0800 dispatch_once_t-Demo[51477:2436486] before: -1--0x1001100f8
發(fā)現(xiàn):
第一次[User sharedInstance],static dispatch_once_t user_onceToken 初始值為0阱驾。
然后進入了block就谜,static dispatch_once_t user_onceToken 變成了768。
第二次調(diào)用[User sharedInstance]啊易,static dispatch_once_t user_onceToken 初始值為-1吁伺,沒有進入block。
第三次調(diào)用[User sharedInstance]租谈,static dispatch_once_t user_onceToken 初始值為-1,沒有進入block捆愁。
而且從頭到位靜態(tài)變量指針沒有發(fā)生變化割去。
猜想:是不是修改static dispatch_once_t user_onceToken;這個靜態(tài)變量的值,就可以控制block是否執(zhí)行昼丑。
#import <Foundation/Foundation.h>
@interface User : NSObject
@property (nonatomic, strong) NSString *job;
+ (User *)sharedInstance;
- (void)deleteUser;
@end
static dispatch_once_t user_onceToken;
@implementation User
+ (User *)sharedInstance {
static User *user = nil;
NSLog(@"before: %ld--%p",user_onceToken, &user_onceToken);
dispatch_once(&user_onceToken, ^{
NSLog(@"after: %ld--%p",user_onceToken, &user_onceToken);
user = [[User alloc]init];
});
return user;
}
- (void)deleteUser {
user_onceToken = 0;
}
@end
調(diào)用單例
[User sharedInstance].job = @"iOS developer";
NSLog(@"%@====%@",[User sharedInstance],[User sharedInstance].job);
[[User sharedInstance] deleteUser];
NSLog(@"%@====%@",[User sharedInstance],[User sharedInstance].job);
輸出結(jié)果
2018-12-02 07:50:46.558717+0800 dispatch_once_t-Demo[51640:2456936] before: 0--0x10e847100
2018-12-02 07:50:46.558891+0800 dispatch_once_t-Demo[51640:2456936] after: 768--0x10e847100
2018-12-02 07:50:46.559008+0800 dispatch_once_t-Demo[51640:2456936] before: -1--0x10e847100
2018-12-02 07:50:46.559091+0800 dispatch_once_t-Demo[51640:2456936] before: -1--0x10e847100
2018-12-02 07:50:46.559624+0800 dispatch_once_t-Demo[51640:2456936] <User: 0x600000012530>====iOS developer
2018-12-02 07:50:46.560110+0800 dispatch_once_t-Demo[51640:2456936] before: -1--0x10e847100
2018-12-02 07:50:46.560254+0800 dispatch_once_t-Demo[51640:2456936] before: 0--0x10e847100 //改為0
2018-12-02 07:50:46.560501+0800 dispatch_once_t-Demo[51640:2456936] after: 768--0x10e847100
2018-12-02 07:50:46.560983+0800 dispatch_once_t-Demo[51640:2456936] before: -1--0x10e847100
2018-12-02 07:50:46.561175+0800 dispatch_once_t-Demo[51640:2456936] <User: 0x604000007f00>====(null)
大功告成呻逆,只需要把dispatch_once_t user_onceToken改成0,就重新初始化User了菩帝。