How to use dispatch_once,
so the given code is executed once, per instance lifetime.
Equivalent would be to have a property inside the object, and use it like this:
- (void)viewWillAppear:(..).. {
// ...
if (self.isDispatched == NO) {
// ...
self.isDispatched = YES;
}
}
But I don't want to use an extra property, but the dispatch_once_t
or similar.
Your requirements can't be satisfied. dispatch_once
can only be used on memory that's never been written to before, and you have no way to guarantee this with instance variables. Greg Parker says so, and he's the guy who would know.
Instead, use the code in your question, but wrap it in a @synchronized
block.
If you really want to avoid adding instance variables, you could use a separate singleton to manage a mutable set. You'd have to register instances with it and remove them on deallocation. Make sure this helper class only holds weak references; see NSMapTable
and NSMapTableWeakMemory
.
For those of you who are curious and as an extra tip, for me this approach has been useful for this purpose:
class SomeVC : UIViewController {
private var token: dispatch_once_t = 0
public override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
dispatch_once(&token) { () -> Void in
self.doSomethingOnce()
}
}
}
By not declaring a static var it has the expected behaviour. That being said, this is definitely NOT RECOMMENDED for any serious project, since in the Docs (as your well said) it states:
The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage (including Objective-C instance variables) is undefined.
If we don't want to run into any future weird bugs and undefined behaviour I would just stick to what Apple says. But it's still nice to play around with these things, isn't it? =)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With