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? =)
Related
Imagine that we have some singleton object:
class Singleton {
static var shared = Singleton()
private init() { ... }
}
Am I right that if I don't keep the reference in some place, it is initialised again and again due to the ARC every time I access it, like this:
Singleton.shared.doSomething()
var a = Singleton.shared.returnSomething()
If I am, where to keep the reference in the iOS app? In classes that use the singleton?
Or in AppDelegate, to ensure using the same instance without repeated initialisation?
By assigning it to a static value you retain the shared instance and don't need to reinitialise it. Static values exist at class level, not instance level, so are retained, effectively, indefinitely.
I am programming a board game. There are a couple of screen and many functions. I often need to change some variable like "money" or "wood".
I added "didset" so I can update a View that displays the amount of money.
I see two options for this. Either a global variable
var money = 0 {didSet {NotificationCenter.default.post(name: NSNotification.Name(rawValue: "showMoney"), object: nil)}}
or a singleton
class resources {
static let shared = resources()
var money = 0 {didSet {NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ResourcenAnzeigen"), object: nil)}}
private init() {}
}
Now I read singletons are always preferred instead of globals. But I wonder why. In my example both seem to do the same. The only difference is I either have to write
money += 1
or
resources.shared.money += 1
The first one looks easier.
And is there a third better way? I read one could give over the needed variables to every function or viewcontroller - but that looks to me like much unneccessary extra code?
Actually a Singleton is a special case of a global variable.
Accessing the global Singleton instance is just shadowed.
This helps to keep the global namespace cleaner.
But a Singleton SHOULD NOT be used for global accesses.
In iOS Singletons are used for unique resources like file system, network, user data, etc.
I suggest you to create an instance at the root of your application and inject this where you need it.
This makes also testing easier and keeps your code clean.
There you can also use the observer pattern to avoid the global NotificationCenter.
FYI: Communication Patterns
Singleton would be the right way to do.
The main problem with using a global variable instead of a singleton for these purposes would be that in case you have a local variable money in some other entity, the compiler would not be implicitly able to identify which money you were referring to.
So, in case you decide to add money as a variable at some other location, and you try to update this global money variable inside the same, it would end up modifying your local variable, and would not update your global one.
But, when you are using a singleton to set or get such a property, you would be safe from this situation.
var money = 0
class MyClass {
var money = 0
func doSomethingAndIncrementGlobalMoney() {
money += 1
}
}
print(money) // Prints 0
let myObject = MyClass()
myObject.doSomethingAndIncrementGlobalMoney()
print(money) // Prints 0, while the expectation was to increment the global 'money' by 1.
Or, you could just go with using something like:
struct MyGlobalItems {
static var money: Int = 0
}
// Using the variable:
MyGlobalItems.money += 1
I've made a small class to test when object declaration occurs.
class MyObject
{
static let instance = MyObject();
required init()
{
println("init")
}
}
And when I run this, "init" is only printed when I reference MyObject.instance, meaning that static variables are declared lazily.
The reason I need this to be eager is because
I want to keep a lookup table of object instances for myself (with weak references, don't worry). Instances to be inserted during their init and expose a lookup function, so the functionality is encapsulated.
I'd prefer if I didn't need a separate function at App start to make references to static variables to achieve this.
I am not aware of an eager keyword, but is there an accepted solution to this? Will it be added in Xcode 7?
I want to create a Helper.swift file to add some functions/methods that are useful in different parts of my app.
I was wondering what is the best practice (if there is one): create a class and only create type methods or just create functions?
I would generally lean towards using a type methods on an appropriately named type, in order to give your helper methods context and avoid polluting the global namespace.
In Swift, structs are an ideal candidate for this sort of construct:
struct Helper {
static func helpfulMethod() { ... }
}
I also use embedded structs with static constants quite liberally in my top level types in order to group related constants within my code.
In writing custom Swift types, you should generally consider using structs first, and only resort to classes when inheritance, reference semantics (as opposed to the implicit copying with value semantics) or ownership semantics (unowned/weak) are required. In this case, your utility functions will be stateless, and there is no inheritance to speak of, so a struct should really be preferred over a class.
I would argue that in general, the Swift language is moving away from global functions in favour of the implicit namespacing provided by types (and protocols/generics). But it's still largely a matter of style/personal preference, and for something as simple as a utility function it's of little consequence.
It is not necessary to create a class or a struct. You can simply put the functions directly in Helper.swift file. And you dont even need to import this file by writing import statements.
To test it out create a file called helper.swift and just add the following lines of code to the file. No class or struct is required.
import Foundation
func addTwo(x: Int) {
return x+2
}
To use this function in any other file just call the function with the required arguments.
let a = addTwo(9)
I prefer this method because when you call the function then you dont have to call it on an instance of a class/struct. Secondly, it leads to cleaner code as you don't have to make each function a class function or a static function.
I will prefer type method because by this way you can easily differentiate your methods.
Suppose you have 50 to 60 methods in which some methods are for designing purpose, some methods are for calculation purpose and some methods are for getting and posting data on server.
Now in this scenario, if you create all these methods as globally it will become hard to recognise and remember.
Now if you differentiate this methods in some class/struct like below:
Methods which are use for Designing purpose make a DesignHelper class/struct and put all these methods into it as class/static method
Methods which are use for calculation purpose make a MathHelper class/struct and put all these method into it as class/static method
Methods which are use for process data with server make a ConnectionHelper class/struct and put all these method into it as class/static method
By using this way you can easily find out any of the method and it will also help in auto completion.
Thank you.
Class functions through a single class work but generally those functions that are being used throughout your app will reuccur on the same objects. A cleaner way is to define your functions in extensions of the object that will use the function. You could put all your extensions in Helper.swift
e.g.
extension UIColor
{
class func randomColor() -> UIColor
{
var randomRed:CGFloat = CGFloat(drand48())
var randomGreen:CGFloat = CGFloat(drand48())
var randomBlue:CGFloat = CGFloat(drand48())
return UIColor(red: randomRed, green: randomGreen, blue: randomBlue, alpha: 1.0)
}
}
with usage like this page.backgroundColor = UIColor.randomColor()
So you can still define your functions as class functions or object functions depending on the usage, but within the extension of the object.
This keeps your code clear so you dont route your calls through the helper throughout your code base. Its clearly defined for the object that will be needing the function. If you find code that does not make sense in an extended function then the function probably needs refactoring into more focused functionaly.
I don't know if it is the best practice but here is how I do it.
First I declare a protocol:
protocol UtilityType { }
Then I extend it (For example a utility function for UIViewController)
extension UtilityType where Self: UIViewController {
func setDefaultTitleAttributes() {
navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
}
}
And I use it like this
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setDefaultTitleAttributes()
}
}
extension MyViewController: UtilityType {}
Solution #1:
class Helper {
class func classMethod() {
// TODO: play something
}
}
And call it:
Helper.classMethod()
In Apple doc:
Structures are always copied when they are passed around in your code, and do not use reference counting.
Solution #2:
struct Helper {
static func classMethod() {
// TODO: do something
}
}
And use it:
Helper.classMethod()
I think solution#2 better than solution#1 because it's not increase reference counting.
UPDATED: I tested with playground. See the result below:
Hope this helps!
This question already has answers here:
Singleton Instance vs Class Methods
(2 answers)
Closed 9 years ago.
So, pretty simple question. Ignoring the implications of over-use of the singleton pattern. I'm trying to find a reliable singleton patter in Objective-C. I have come across this:
#implementation SomeSingleTonClass
static SomeSingleTonClass* singleInstance;
+ (SomeSingleTonClass*)getInstance
{
static dispatch_once_t dispatchOnceToken;
dispatch_once(&dispatchOnceToken, ^{
singleInstance = [[SomeSingleTonClass alloc] init];
});
return singleInstance;
}
- (void)someMethodOnTheInstance
{
NSLog(#"DO SOMET WORK")
}
#end
This I am fairly happy with but it leads to a lot of this:
[[SomeSingleTonClass getInstance] someMethodOnTheInstance];
My question is, why is this better than a purely static class.
#implementation SomeStaticClass
static NSString* someStaticStateVariable;
- (id)init
{
//Don't allow init to initialize any memory state
//Perhaps throw an exception to let some other programmer know
//not to do this
return nil;
}
+ (void)someStaticMethod
{
NSLog(#"Do Some Work");
}
All you really gain, is mildly cleaner looking method calls. Basically you swap out this:
[[SomeSingleTonClass getInstance] someMethodOnTheInstance];
For this
[SomeStaticClass someStaticMethod];
This is a minor simplification for sure, and you can always store the instance within your class. This is more intellectual curiosity, what Objective-C god am I pissing off by using static classes instead of singletons? I'm sure I can't be the first person to think this, but I promise, I did a duplicate search first. The few answers I found, I felt like were based on older versions of cocoa, because even the discussed singleton patterns seemed to suffer from threading issues.
Static class : Used when you want to group together utility methods that are state independent.
Singleton : Used when you have multiple methods that share a state.
I've found it convenient to do a mix of both. I use a standard singleton pattern similar to your first that results in:
[[MyClass defaultInstance] doSomething];
But I also want to be able to create other instances of the same class:
MyClass *secondInstance = [[MyClass alloc] init];
[secondInstance doSomething];
When I want more concise access to call methods on the singleton instance, I define class methods as follows:
// class method to call a method on the singleton instance
+ (void)doSomething
{
[[MyClass defaultInstance] doSomething];
}
So with that, I can use:
[MyClass doSomething];
You're pissing off no Objective-C gods with a class like that. Actually, Apple recommends to use that pattern in some cases (I think they mentioned this in one of the ARC session videos, where they discussed common design patterns and how to implement them using ARC).
In other cases, where you can have multiple instances of a class, but want a default one, you'll of course have to use the shared instance approach.
The first example seems to be needlessly creating a singleton-like instance of a class. I say needlessly because from your other comments it appears that the class doesn't declare any properties or instance variables. Given that the fundamental purpose of an object is to provide storage for state, an object with no instance variables is rarely a useful thing.
Your second example shows a class that would never be instantiated. Again, the fundamental purpose of a class in Objective-C is to act as a factory for instances, so a class that's never instantiated isn't really useful or necessary.
Instead, you can just provide a set of C functions. C functions don't need to be associated with a class at all. So consider doing something like this:
static NSString* someStaticStateVariable;
void someFunction(void)
{
NSLog(#"Do Some Work");
}
The functions can be in separate .h/.m pair, or can be incorporated in the .h/.m for an existing class if it makes sense to do so (generally, if the functions are closely associated with the concerns of that class).