Use self in singleton struct - swift

I have a simple question about singleton in swift, after a lot of research I didn't find a clear answer for that. So question is - I have a StructA:
struct StructA {
static let shared = StructA()
private init() {}
public func someFuncA() {
//self.somefuncB()
//or
//StructA.shared.someFuncB()
}
private func someFuncB() {
}
}
I call someFuncA from other class like this StructA.shared.someFuncA():
Can you please explain me what the difference self.somefuncB() and StructA.shared.someFuncB() (see above code) ?
In my opinion there is no difference, but what if I have such code when self.somefuncB() must be called in callback -
So must I use [weak self]?
public func someFuncA() {
someFuncWithCallback() { [weak self] in
self?.somefuncB()
}
}
or can I just write
public func someFuncA() {
someFuncWithCallback() {
StructA.shared.someFuncB()
}
}
I checked this code with "Leaks" (Xcode instruments) it says that there is no leak, as I know closer/block owns objects that used in it, so can someone explain me what here happens ? thanks.

A couple of thoughts:
A struct singleton is a contradiction in terms. A singleton is an object where there should be only one instance. But struct is a value-type and has "copy" memory semantics. Consider:
var a = StructA.shared
...
The a is a copy of the so-called singleton, not a reference to it. To avoid this problem, the singleton should be a class, a reference type.
I agree with Paulw11, that self is a simpler and more common approach. I'd also suggest, though, that by referencing self, you can better write code that (a) is not dependent on the class being a singleton; and (b) opens the possibility of the class being subclassed at some future date.
Given that I would advise self pattern, I would therefore also suggest avoiding obvious potential strong reference cycles (e.g. by employing weak or unowned references where needed). There's no point in knowingly creating what could be strong reference cycle simply because it happens to be a singleton. Why write code that you know you'd have to rewrite if you ever revisited the decision to use singleton pattern, especially when you know how easy it is to avoid strong references in the first place?
FYI, I'm seeing the same behavior that you report, that if a static participates in a theoretical strong reference cycle, it's not identified as such. But if you set that static property to nil (assuming it was variable and optional), the strong reference appears.
This observation doesn't change my recommendation above, namely to avoid what you know would be a strong reference cycle in any other context. I'm merely confirming your empirical observation.
Regarding points 2 through 4 above (where I contemplate some potential eventual refactoring of singleton pattern into some other pattern), I should say that this is not a purely academic observation. It's not uncommon to have some singleton type, and later, as the project becomes more complicated or employs more unit tests, to revisit that decision and start employing dependency injection or other patterns. It would be a shame if you had to edit all of the individual functions as well. If you write the code to not depend upon the singleton nature of the object, you end up with more robust code base with fewer unnecessary internal dependencies.

Related

In swift, why can't I instantiate a protocol when it has an initialiser?

I understand that generally I cannot instantiate a protocol.
But if I include an initialiser in the protocol then surely the compiler knows that when the protocol is used by a struct or class later, it will have an init which it can use?
My code is as below and line:
protocol Solution {
var answer: String { get }
}
protocol Problem {
var pose: String { get }
}
protocol SolvableProblem: Problem {
func solve() -> Solution?
}
protocol ProblemGenerator {
func next() -> SolvableProblem
}
protocol Puzzle {
var problem: Problem { get }
var solution: Solution { get }
init(problem: Problem, solution: Solution)
}
protocol PuzzleGenerator {
func next() -> Puzzle
}
protocol FindBySolvePuzzleGenerator: PuzzleGenerator {
var problemGenerator: ProblemGenerator { get }
}
extension FindBySolvePuzzleGenerator {
func next() -> Puzzle {
while true {
let problem = problemGenerator.next()
if let solution = problem.solve() {
return Puzzle(problem: problem, solution: solution)
}
}
}
}
The line:
return Puzzle(problem: problem, solution: solution)
gives error: Protocol type 'Puzzle' cannot be instantiated
Imagine protocols are adjectives. Movable says you can move it, Red says it has color = "red"... but they don't say what it is. You need a noun. A Red, Movable Car. You can instantiate a Car, even when low on details. You cannot instantiate a Red.
But if I include an initialiser in the protocol then surely the compiler knows that when the protocol is used by a struct or class later, it will have an init which it can use?
Protocols must be adopted by classes, and there might be a dozen different classes that all adopt your Puzzle protocol. The compiler has no idea which of those classes to instantiate.
Protocols give us the power to compose interfaces without the complexity of multiple inheritance. In a multiple inheritance language like C++, you have to deal with the fact that a single class D might inherit from two other classes, B and C, and those two classes might happen to have methods or instance variables with the same name. If they both have a methodA(), and B::methodA() and C::methodA() are different, which one do you use when someone call's D's inherited methodA()? Worse, what if B and C are both derived from a common base class A? Protocols avoid a lot of that by not being directly instantiable, while still providing the interface polymorphism that makes multiple inheritance attractive.
I understand that I can't do it - I just want to understand why the
compiler can't do it?
Because protocols in Swift represent abstraction mechanism. When it comes to abstraction, you could think about it as a template, we don't have to care about the details of how it behaves or what's its properties; Thus it makes no sense to be able to create an object from it.
As a real world example, consider that I just said "Table" (as an abstracted level), I would be pretty sure that you would understand what I am talking about! nevertheless we are not mentioning details about it (such as its material or how many legs it has...); At some point if I said "create a table for me" (instantiate an object) you have the ask me about specs! and that's why the complier won't let you create object directly from a protocol. That's the point of making things to be abstracted.
Also, checking: Why can't an object of abstract class be created? might be helpful.
Unfortunately swift does not allow that even with such "hack"
You would need to use a class that confirms to that protocol as an object you refer to.
When you instantiate an object, the Operating System has to know how to allocate and deal with that kind of object in the memory: Is it a reference type (Classes)? Strong, weak or unowned reference? Or is it a value type (Structs, Strings, Int, etc)?
Reference types are stored in the Heap, while value types live in the Stack. Here is a thorough explanation of the difference between the two.
Only Reference and Value types (objects) can be instantiated. So, only the objects that conform to that protocol can then be instantiated, not the protocol itself. A protocol is not an object, it is a general description or schema of a certain behavior of objects.
As to Initialization, here what the Apple docs say:
Initialization is the process of preparing an instance of a class,
structure, or enumeration for use. This process involves setting an
initial value for each stored property on that instance and performing
any other setup or initialization that is required before the new
instance is ready for use.

Swift: refactor singleton pattern

I have a Swift singleton class that maintains app state by storing several arrays. What is the best practices' way to go here? Should we change it, and if we do, then how?
Here is the singleton class:
import Foundation
class FilterModel {
static let sharedInstance = FilterModel()
private init() { }
var muscleExercisesArray = [Int]()
var equipmentExercisesArray = [Int]()
var typeExercisesArray = [Int]()
}
If you're wondering about the basic singleton pattern, a couple of observations:
I might suggest you declare the class to be final, too, to avoid having some future developer subclass it and introduce confusion about to what type sharedInstance refers.
I might also suggest that in Swift 3, the convention is to simplify the name of sharedInstance to just shared. It's not a hard and fast rule, but is the emerging standard.
This implementation is not thread-safe. If you're ok with that, I'd at least include some warning in the comments warning future developers of this concern. Or, obviously, with a little work you could change this to be thread-safe by wrapping this all in some internal synchronization mechanism.
You said:
Singletons are considered a bad approach towards app architecture, so I was wondering what to do instead of it when we need to maintain app state. Somehow I can not find anything online except for DI approach that does not work (or I do not know how) in this case when we need app state to be modified by different files
Yes, singletons are not ideal for model objects for a number of reasons (makes unit testing harder; makes responsibilities unclear, etc.) and there are better patterns (see What's Alternative to Singleton). At the very least, one simple approach is to have app delegate or root view controller instantiate this model object and then only pass this to whatever subsequent controllers need access to it (e.g. in prepareForSegue). This way, it's explicit which objects might be interacting with the model, making responsibilities a little more clear.

Closure identity in swift: unregister observing closure

When rethinking my everyday programming patterns to be more swifty, there is one, that I really struggle with: observing changes. After a lot of thinking and research I have yet to find a satisfying solution. That is one,
that is easy to use,
leverages the full potential of swift's strong type system,
is compatible with value types and
allows for static dispatch.
Maybe the latter one is not possible and that's the reason why my search is unsuccessful so far. If so, I would like to know why?
Some of the work-arounds I found so far:
SO: Observer Pattern in Swift (Using Any or objective_c runtime functionality)
Solving the binding problem with Swift (IMHO rather awkward to use)
The ones based on closures e.g Answer by Airspeed Velocity
The third one is so far the one that ticks the most boxes it's type safe, straight forward to use, and compatible with value types. For reference:
// central part is an observable protocol that can be fulfilled by
// any observable type.
protocol Observable {
associatedtype Value
func register(f: Value->())
}
// this would be implemented like
struct ObeservableInt: Observable {
// observable value
var value: Int {
didSet {
// inform all observers
for f in observers {
f(value)
}
}
}
var observers = Array<Int->()>()
mutating func register(f: Int->()) {
observers.append(f)
}
}
So far so good. But what happens if our observer is not needed any more? To avoid a memory leak we should unregister it. But this is seemingly not possible with this architecture. Despite being reference types, closures don't have a reliable identity. That is unless we force dynamic dispatch by annotation with #objc_block. Another alternative is to return a token from register(f:) and use that in an the unregister(token:) call.
So my question is, are there any better alternatives regarding the listed criteria? If not, which one of the two solutions #objc_block or using token is the preferred one?

Any reason not use use a singleton "variable" in Swift?

For Sept 2015, here's exactly how you make a singleton in Swift:
public class Model
{
static let shared = Model()
// ( for ocd friends ... private init() {} )
func test()->Double { print("yo") }
}
then elsewhere...
blah blah
Model.shared.test()
No problem.
However. I add this little thing...
public let model = Model.shared
public class Model
{
static let shared = Model()
func test()->Double { print("yo") }
}
then, you can simply do the following project-wide:
blah blah
model.test()
Conventional idiom:
You see Model.shared.blah() everywhere in the code.
"My" idiom:
You see model.blah() everywhere in the code.
So, this results in everything looking pretty!
This then, is a "macro-like" idiom.
The only purpose of which is to make the code look pretty.
Simplifying appearances of ImportantSystem.SharedImportantSystem down to importantSystem. throughout the project.
Can anyone see any problems with this idiom?
Problems may be technical, stylistic, or any other category, so long as they are really deep.
As a random example, here's an "article in singletons in Swift" that happens to also suggest the idea: https://theswiftdev.com/swift-singleton-design-pattern/
Functionally, these are very similar, but I'd advise using the Model.shared syntax because that makes it absolutely clear, wherever you use it, that you're dealing with a singleton, whereas if you just have that model global floating out there, it's not clear what you're dealing with.
Also, with globals (esp with simple name like "model"), you risk of having some future class that has similarly named variables and accidentally reference the wrong one.
For a discussion about the general considerations regarding globals v singletons v other patterns, see Global Variables Are Bad which, despite the fairly leading title, presents a sober discussion, has some interesting links and presents alternatives.
By the way, for your "OCD friends" (within which I guess I must count myself, because I think it's best practice), not only would declare init to be private, but you'd probably declare the whole class to be final, to avoid subclassing (at which point it becomes ambiguous to what shared references).
There are a few things to look out for when using this approach:
The global variable
A global variable in itself is no big deal, but if you have quite some global variables, you might have trouble with autocompletion, because it will always suggest these global variables.
Another problem with global variables is that you could have another module in your application (written by you or otherwise) define the same global variable. This causes problems when using these 2 modules together. This can be solved by using a prefix, like the initials of your app.
Using global variables is generally considered bad practice.
The singleton pattern
A singleton is helpful when working with a controller, or a repository. It is once created, and it creates everything it depends on. There can be only one controller, and it opens only one connection to the database. This avoids a lot of trouble when working with resources or variables that need to be accessed from throughout your app.
There are downsides however, such as testability. When a class uses a singleton, that class' behaviour is now impacted by the singletons behaviour.
Another possible issue is thread safety. When accessing a singleton from different threads without locking, problems may arise that are difficult to debug.
Summary
You should watch out when defining global variables and working with singletons. With the appropriate care, not many problems should arise.
I can't see a single downside to this approach:
You can use different variables for different parts of the program (-> No namespace cramming if you don't like this I guess)
It's short, pretty, easy to use and makes sense when you read it. Model.shared.test() doesn't really make sense if you think about it, you just want to call test, why would I need to call shared when I just need a function.
It uses Swift's lazy global namespace: The class gets allocated and initialized when you use it the first time; if you never use it, it doesn't even get alloced/inited.
In general, setting aside the exact idiom under discussion, regarding the use of singletons:
Recall that, of course, instead of using static var shared = Model() as a kind of macro to a singleton, as suggested in this Q, you can just define let model = Model() which simply creates a normal global (unrelated to singletons).
With Swift singletons, there has been discussion that arguably you want to add a private init() {} to your class, so that it only gets initialized once (noting that init could still be called in the same file).
Of course in general, when considering use of a singleton, if you don't really need a state and the class instance itself, you can simply use static functions/properties instead. It's a common mistake to use a singleton (for say "calculation-like" functions) where all that is needed is a static method.

Combine generics and extensions in Swift?

Looking at:
Using a dispatch_once singleton model in Swift
I see a very generic pattern for creating a shared singleton instance of my class. What I'd like to be able to do is create an extension for "all classes" that implements this sharedInstance method with generics.
I don't see any syntax for doing this; anybody want to take a crack at it?
As others have pointed out, Swift offers a simpler way to create singletons.
As an example: let's say we have a class called Model, and we want to have a single instance, visible throughout our app. All we need to write in the global scope is:
let modelSingleton = Model()
This will create an instance of the Model class, visible everywhere, and that cannot be replaced by another instance (Hmmm, that's pretty much what one would expect from a singleton, isn't it?).
Now, this way of doing would, on the other hand, still allow you to create other Model instances, apart from the singleton. While this departs from the official definition of singletons in other languages, this approach would have the interesting advantage of allowing the creation of other instances for testing purposes (singletons have bad press in the unit testing world :) ).
Swift will soon offer everything needed to create real Singleton<T> classes (it's hard now because class vars aren't allowed yet). But that being said, the approach described above will probably be more than enough for many Swift programmers.
I don't think this is possible.
Even if it was possible to extend Any / AnyObject, every object would share the same implementation of the sharedInstance singleton getter, and therefore the same static instance variable. Thus, instance would get set to an instance of the first class on which sharedInstance was called.
extension Any {
class var sharedInstance:TPScopeManager {
get {
struct Static {
static var instance : TPScopeManager? = nil
}
if !Static.instance {
Static.instance = TPScopeManager()
}
return Static.instance!
}
}
}
...
NSString.sharedInstance() // Returns an NSString
NSArray.sharedInstance() // Returns the same NSString object!
In Swift you can make an extension to NSObject, but you can't extend Any/AnyObject