重置dispatch

编程入门 行业动态 更新时间:2024-10-26 17:27:25
重置dispatch_once是否安全(不涉及线程)(Is it safe to reset a dispatch_once (no threading involved))

我想知道重置dispatch_once是否安全(不涉及线程):

我的情况是整个应用程序我缓存NSDateFormatters和NSNumberFormatters等。 我通过将它们包装在dispatch_once调用中来完成此操作。

现在当我得到区域设置发生变化的NSNotification时,id就像重置了一些dispatch_once标记,所以下次需要格式化时,它们会再次分配。

我只是让每个vc观察通知并将标记的值重置为0。

这个可以吗? 感觉......一方面有点脏,但也可以,因为替代方案是使用BOOLS并用if替换调度调用。

#import "ViewController.h" static dispatch_once_t onceToken; @implementation ViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; [[NSNotificationCenter defaultCenter] addObserverForName:NSCurrentLocaleDidChangeNotification object:self queue:nil usingBlock:^(NSNotification *note) { onceToken = 0; } } //image this called every second... - (void)viewDidAppear:(BOOL)animated { //need a for matter only here static NSDateFormatter *formatter; dispatch_once(&onceToken, ^{ formatter = [[NSDateFormatter alloc] init]; }); NSLog(@"%@", [formatter stringFromDate:[NSDate date]]); } @end

Id like to know if it is safe to reset a dispatch_once (no threading involved):

my case is that all over the app I cache NSDateFormatters and NSNumberFormatters and other. I do this by wrapping them in dispatch_once calls.

Now when I get the NSNotification that the locale changed, id like to reset some of those dispatch_once tokens, so the next time the formatters are needed, they allocate again.

I would simply make each vc observe the notification and reset the values of the tokens to 0.

is this ok? It feels.. a bit dirty on the one hand but also ok since the alternative would be to use BOOLS and replace the dispatch call with an if..

#import "ViewController.h" static dispatch_once_t onceToken; @implementation ViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; [[NSNotificationCenter defaultCenter] addObserverForName:NSCurrentLocaleDidChangeNotification object:self queue:nil usingBlock:^(NSNotification *note) { onceToken = 0; } } //image this called every second... - (void)viewDidAppear:(BOOL)animated { //need a for matter only here static NSDateFormatter *formatter; dispatch_once(&onceToken, ^{ formatter = [[NSDateFormatter alloc] init]; }); NSLog(@"%@", [formatter stringFromDate:[NSDate date]]); } @end

最满意答案

dispatch_once单例模型用于提供线程安全性。 如果你肯定只会从主UI线程访问单例(就像在这种情况下似乎),没有充分的理由不回到旧的单例模型:

static NSDateFormatter* myFormatter; +(NSDateFormatter*)mySingletonFormatter { if(!myFormatter) { myFormatter = [...]; } return myFormatter; } +(void)resetMyFormatter { myFormatter = nil; }

如果必须同时执行这两项操作(在多线程环境中重置),则可以包装格式化程序创建并在@synchronized(self)中重置。

我会避免修改dispatch_once_t的私有位,因为它没有记录它的使用方式(虽然它暗示将其重置为0将清除它,但没有记录。)为了保持线程安全,你必须将整个东西包装在信号量中,所以不妨回到已知的文档化解决方案。

The dispatch_once singleton model is used to provide thread-safety. If you're positive that the singleton will only ever be accessed from the main UI thread (as it seems in this case) there's no substantial reason not to fall back to the older singleton model:

static NSDateFormatter* myFormatter; +(NSDateFormatter*)mySingletonFormatter { if(!myFormatter) { myFormatter = [...]; } return myFormatter; } +(void)resetMyFormatter { myFormatter = nil; }

If you have to do both (reset in a multithreaded environment) the you can wrap the formatter creation and reset in @synchronized(self).

I would avoid modifying the private bits of dispatch_once_t since it's undocumented how it's used (although it's implied that resetting it to 0 will clear it, it's not documented.) To maintain thread safety, you would have to wrap the whole thing in semaphores anyway, so might as well just fall back to a known documented solution.

更多推荐

本文发布于:2023-07-29 18:26:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1318601.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:dispatch

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!