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
Related
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.
I'm faced with a situation where I am defining a reusable base class in a module, and I want to provide certain functions that should be callable only by subclasses, not external users of that subclass.
I'm writing a framework and packaging it as a Swift module. Part of my framework includes a base class that can be subclassed to add functionality, but whereby the derived class also has a further external purpose as well. Imagine defining a new kind of view: it derives from UIView or NSView, then provides additional logic, and is then itself instantiated by another party.
In this case, I'm the one defining the UIView-like class that is intended to be subclassed, and along with it comes a lot of private UIView internal stuff, like measurement, arranging, who knows, internal stuff.
The point is, end users of this new view class don't want to see the internals of the architecture that supported the subclassing, those should be completely inside the black box of what the subclass represents.
And it strikes me that this is now impossible in Swift.
I really don't understand why Swift got rid of protected access control. According to Apple, the function that I want to expose only to subclasses "isn't really useful outside the subclass, so protection isn’t critical".
Am I missing something? Is this a whole class of design patterns that Swift simply cannot support?
One thought that occurs to me is I could perhaps split up the public-public and the private-public parts of my class into two parts, perhaps using protocols, whereby public-public users would only see the public protocol and "private" public users would see the "private" protocol as well. Alas this seems like a lot of engineering for something that used to be free.
FWIW — I've been continually asking for better access control in Swift (including protected) since before there was access control in Swift. Now, 3.5 years after we were told to give the Swift approach to access control a try, Swift has been my primary language for almost 3 of those years and I still think the access control paradigm is clumsy and unable to model concepts that are easy in almost all similar languages.
The largest mitigating factor for me is that Swift has steered me away from ever using inheritance and subclassing 95% of the time, which I think is a good thing. So this issue comes up less than it may have otherwise. But for situations exactly as you are describing, there isn't an equivalent way to accomplish what you are doing using only protocols and protocol extensions, so you are stuck either polluting a public API with possibly harmful internal details, or using some workaround (like the one that follows) which has the smallest possible public API exposure, and simulates what you want at the cost of boilerplate and awkwardness.
That said, the approach I take is somewhat inspired by Objective C, where there is also no real protected access control, but the convention is to declare a public API header (which client code will import and reference) and a special "+Subclassing" header which only subclasses will import in their implementation, giving them visibility into the not-for-public-consumption internals.
In Swift, this isn't directly possible either, but given a class like this:
open class SomeClass {
private var foo: String
private var bar: Data
public init(){
foo = "foo"
bar = Data()
}
private func doInternalThing() {
print(foo)
}
}
You can add a nested "Protected" wrapper via extension (has to be in the same file as your class declaration), which takes an instance of the class (or a subclass) and exposes the protected-level internals as a sort of proxy:
// Create a nested "Protected" type, which can accept an instance of SomeClass (or one of its subclasses) and expose the internal / protected members on it
public extension SomeClass {
public class Protected {
unowned private var someClass: SomeClass
public var foo: String {
get {
return someClass.foo
}
set {
someClass.foo = newValue
}
}
public init(_ someClass: SomeClass) {
self.someClass = someClass
}
public func doInternalThing() {
someClass.doInternalThing()
}
}
}
Outside of the framework, in the client application, the protected members are accessed in a subclass like this:
class SomeSubclass: SomeClass {
private lazy var protected: SomeClass.Protected = { SomeClass.Protected(self) }()
func doSomething() {
protected.foo = "newFoo" // Accesses the protected property foo and sets a new value "newFoo"
protected.doInternalThing() // Prints "newFoo" by calling the protected method doInternalThing which prints the foo property.
}
}
There are pros and cons for this approach. The cons are mainly the amount of boilerplate you need to write to map all your properties and functions from the Protected wrapper to the actual class instance as shown above. Also, there is no avoiding the fact that consumers will see SomeClass.Protected as a publicly visible type, but hopefully it's clear that it shouldn't be used and it's difficult enough to use it arbitrarily that it won't happen.
The pros are that there isn't a lot of boilerplate or pain for clients when creating subclasses, and its easy to declare a lazy "protected" var to get the desired API. It's pretty unlikely that non-subclass would stumble upon or use this API accidentally or unwittingly, and it's mostly hidden as desired. Instances of SomeSubclass will not show any extra protected API in code completion or to outside code at all.
I encourage anyone else who thinks access control — or really in this case, API visibility and organization — to be easier than it is in Swift today to let the Swift team know via the Swift forums, Twitter, or bugs.swift.org.
You can kinda, sorta work around it by separating out the for-subclasses stuff into a separate protocol, like this:
class Widget {
protocol SubclassStuff {
func foo()
func bar()
func baz()
}
func makeSubclassStuff() -> SubclassStuff {
// provide some kind of defaults, or throw a fatalError if this is
// an abstract superclass
}
private lazy var subclassStuff: SubclassStuff = {
return self.makeSubclassStuff()
}()
}
Then you can at least group the stuff that's not to be called in one place, to avoid it polluting the public interface any more than absolutely necessary and getting called by accident.
You can also reconsider whether you really need the subclass pattern here, and consider using a protocol instead. Unfortunately, since protocols can't nest types yet, this involves giving the subclass-specific protocol an Objective-C-style prefixed name:
protocol WidgetConcreteTypeStuff {
...
}
protocol Widget {
var concreteTypeStuff: WidgetConcreteTypeStuff { get }
}
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.
I'm using a singleton in a Swift 3project I've built.
As part of the project I have registration and login view controllers and I figured I might want registration/login in future projects. So for code reuse I thought about having the registration and login functions in separate .swfit classes and then I'd instantiate these classes in the singleton.
Or just have the registration/login functions as static functions in separate files.
I just wasn't sure if that breaks the idea of a singleton and that all the registration/login functions should be in the singleton.
It's a bit hard to come by practical examples of design patterns in my college degree studies, teachers like data structures, and many other coding topics but not so much about design patterns and how to write better structured code.
In general, you should regard view controllers as not reusable, because they mediate between this particular data and this particular interface (model-view).
But if you can isolate this particular functionality into an independent object, that would make it reusable. What I usually do is make a custom struct and have the view controller own this as a helper object. I don't quite see the point of the putting the struct declaration in a separate file, since it's easy to copy and paste, but you can certainly do that if you like.
(Nor do I see what any of this has to do with Singleton.)
For better learning Design Pattern I recommend the fun and easy reading Head First Design Patterns
Regarding your question about a Singleton pattern in Swift code is always best learned with an example:
final class AccountUtility {
//here is object instantiation to meet the Singleton Design Pattern single instance requirement
static let shared = AccountUtility()
//a private constructor ensures no one can create an instance of this class
private init() {
}
func login() {
}
func register() {
}
}
To use this Singleton Swift class:
AccountUtility.shared.login()
Ok so I have a a bunch of helper functions in my project that I originally had in a class called Animate. I was wonder what are the benefits of declaring func vc class func.
Lets use this as an example class:
class Animate{
func moveView(...){
...
}
}
So I believe if I have a class func I don't have to instantiate the class as so.
Animate.moveView(...)
And if I just declare the function with func it would be:
Animate().moveView(...)
However if I don't declare the file as a class at all as so:
func moveView(...){
...
}
When I call the function it is just:
moveView(...)
With no indication where the code came from and it can be just used like this anywhere in the project.
What are the pros and cons of these three ways? Is not declaring a class bad practice? Or, is there some edge case that this is very useful? For example in my situation I have no need for a class since I am just creating helper functions and not an object.
Thanks in advance for any insight on this!
Ok. Instance methods vs class methods vs global methods.
(The term method and function are interchangeable. Method implies a function implemented by an object, so I tend to prefer the term method to the term function.)
An instance method is a method that is performed by instances of a class. You must have an instance of that class to talk to in order to invoke an instance method.
Instance methods have access to the instance variables of the object they belong to, so the object can save state information between calls. (In a networking class you could create multiple download objects, each of which manages an individual file download of a different file from a different URL, and each might have a different delegate it notifies when it's download is complete)
Class methods are invoked by the class itself, not by an instance. This can make it simple to invoke helper functions without having to manage an object to do that work for you. Since class methods don't talk to an instance of the class, they can't preserve different state information for each object. You might have a utilities class that performs localization functions on strings for example. The localization process is self-contained. You call a class function and pass in a string and the language you want it localized to, and it hands you back a result. No need to keep state between calls. Such a call might look like
let frenchString =
LocalizationUtils.localizeString("English String",
toLanguage: "French")
Global functions do not belong to any particular class. They are global to the entire module in which they are defined. They are similar to class functions, except that they are not specific to a particular class.
I agree with (and upvoted) #Duncan C's answer, but just thought I'd throw in a couple of other pros/cons.
I tend to like global functions over class methods because global functions don't clutter up my classes. I like to keep my classes lean and thin. The global functions can be kept in a separate file that I can copy and paste, or import, into a given project as I need them. So I might have a file in my project called AnimateHelperFunctions that is just global functions related to that class. A given project may only need a couple of them, or most of them, or those plus a couple more that I discover I need. I can delete the ones I don't use in a given project from the file so as to keep that file neat and trim.
I just think that global functions are more modular and encourage me to factor out single tasks for a single function - a good global helper function that does exactly one thing and does it perfectly can also sometimes be abstracted or made generic and used in other contexts as well. You might have a project sometime where you realize you don't need the class - you just need its helper function, and there it is.
I would prefer a hundred simple global functions that I can pick and choose from over a giant bloated class.
You can accomplish much the same thing with extensions, of course, and to some degree it is a matter of taste, as there is very little difference (any?) between class methods and global functions except that to use the class method you have to drag along the entire class.
Unlike global state, there isn't any danger in a global function. Sure, anyone can call it, but the same is true of class methods, and the global function can only operate on the arguments you pass to it.
For me, I use static or class methods to control class level properties or if I have to return customised instances of that particular class or struct. Like for example consider I have below struct.
struct Person {
let firstName: String
let lastName: String
}
Now if I am writing some test cases, where I need Person's instance initialized with a particular name John in many of my test classes, I can create a helper static method.
extension Person {
static func john() -> Person {
return Person(firstName: "John", lastName: "Appleseed")
}
}
let john = Person.john() // I could also create a static property instead, but it's a matter of personal choice and situation.
In above case, I could have made john as global function as well but for me, it will be very vague and not readable.
Another place I can think of where I prefer static method is returning count of cases for an enum.
enum Mood {
case happy
case angry
case lazy
case high
static func count() -> Int {
return 4
}
}
There are places, where I use global functions. I use global functions for logging.
func log(screenEvent name: String) {
let tracker = GAI.sharedInstance().defaultTracker
tracker.set(kGAIScreenName, value: screenName)
let builder = GAIDictionaryBuilder.createScreenView()
tracker.send(builder.build() as [NSObject : AnyObject])
}
Internally, the method is using a sharedInstance, creating a global method makes it easily accessible everywhere in the project just like a print function which logs output in console, but this is logging in some custom service.
Some other global functions which I usually include in my projects are GCD helpers.
func delay(delay:Double, closure: dispatch_block_t) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
func backgroundTask(closure: dispatch_block_t) {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), closure)
}
func mainThreadTask(closure: dispatch_block_t) {
dispatch_async(dispatch_get_main_queue(), closure)
}
These function don't need any information about a class so it makes sense to make them global instead of wrapping them inside a class.
Regarding instance methods, as answered by #Duncan C, they are called on instances, when you want to maintain a state. Below example shows usage of both static and instance methods.
enum TapType {
case water
case beer
}
struct Tap {
let tapType: TapType
//static method
static func unlimitedBeer() -> Tap {
let beer = Tap(tapType: .beer)
beer.turnOn(forDuration: Float.greatestFiniteMagnitude)
return beer
}
//instance method: will do operation on a particular instance of `Tap`.
func turnOn(forDuration duration: Float) {
//implementation
}
}
let unlimitedBeer = Tap.unlimitedBeer()
You can always use convenience initializer to initialize an object with custom behaviour, but again, it's a matter of choice. In above example, I couldn't think of any convenience initializer which would give me unlimited beer.