2

How can I create a custom class in swift that is of type Array? To be exact, I have a custom class of type Car, and now I want to create a singleton that is an array of Cars. (Because I want to be able to access it from anywhere in my app).

My workaround is to define my singleton as NSMutableArray. But I see that causes my some problems in my code. So I wish to define it as swift array. How can I do it?

My code now is:

class MyCars: NSMutableArray {
    class var sharedInstance: MyCars {
        struct Static {
            static var instance: MyCars?
            static var token: dispatch_once_t = 0
        }

        dispatch_once(&Static.token) {
            Static.instance = MyCars()
        }

        return Static.instance!
    }
}
bobsacameno
  • 765
  • 3
  • 10
  • 25
  • The Swift array is implemented as struct, which does not support inheritance - so it's not possible – Antonio Jan 14 '15 at 11:49
  • So what I did is the best way to do it? Is there another way to get the functionality that I want? – bobsacameno Jan 14 '15 at 11:51
  • Why do you need inheritance? Wanting to add new methods or override existing ones? – Antonio Jan 14 '15 at 11:54
  • No. I just want to have a singleton which is an `Array` of my `Car`s. But I think the `NSMutableArray` does not doing it perfectly.. – bobsacameno Jan 14 '15 at 11:56
  • @roi.holtzman what did you end up using? i am in the same mindset, in my case i have a custom class Visitor and i like array listVisitors. i also bump upon singleton, but not sure if this is the way to go. In my case i like to add/delete visitors from the list. Would you mind sharing your actual solution?? – alex Dec 18 '15 at 22:02

2 Answers2

3

To create a singleton array of Car you don't need to create a new class - just a struct with a static member:

struct MyCars {
    static var sharedInstance = Array<Car>()
}

Note that the sharedInstance is initialized once - read this answer for more info

Addendum

In case you want to use MyCars to refer to an array of Car, you can just define a typealias and use a different name for the struct containing the singleton, such as:

typealias MyCars = Array<Car>

struct Singleton {
    static var myCars = MyCars()
}
Community
  • 1
  • 1
Antonio
  • 71,651
  • 11
  • 148
  • 165
  • I'm getting an error: `NSArray is not subtype of MyCars`. Do you know how to fix it? – bobsacameno Jan 14 '15 at 12:27
  • my code now is: `class MyCars { class var sharedInstance : MyCars { struct Singleton { static var instance = Array() } return Singleton.instance } }` – bobsacameno Jan 14 '15 at 12:36
  • If you need the class for something else, than it looks good. If it's just a container for the static property only, then I think the struct is better - less code :) – Antonio Jan 14 '15 at 12:38
  • But I have the struct there. I thought I should write it like this so I will have a singleton. You don't know why I the error I mentioned? – bobsacameno Jan 14 '15 at 12:41
  • Sorry didn't see your 1st comment. How did you get that error? Remember that you have to access to the singleton as `MyCars.sharedInstance` – Antonio Jan 14 '15 at 12:45
  • I think I got it :) I did't realise that you meant that I should use the code you wrote exactly. I thought I should've put it inside the singleton code. Anyway, now it works. Thanks! – bobsacameno Jan 14 '15 at 12:52
  • Me too :) it was the code in your 2nd comment giving error. Btw glad you solved. I've updated my answer, so check it out – Antonio Jan 14 '15 at 12:59
0

As I understand it, a singleton represents a class or structure for which there can be only one instance, ever. Even if someone tries to instantiate a new copy of the singleton they will wind up with a pointer back to the sole instance. (I got that idea from the Big Nerd Ranch Guide to iOS Programming, but it doesn't appear to be controversial). I don't think that the struct solution proposed above meets this criteria. For example, in a playground create the the suggested struct (I've substituted 'String' type for 'Car' type to make testing easier):

struct MyCars {
    static var sharedInstance = Array<String>()
}

Then initialize the structure and show that the initialization "took":

MyCars.sharedInstance = ["Granada", "Pinto", "Chevette"]
println( MyCars.sharedInstance )
// prints all three car names

Now try to create a copy of the data and show it works, then modify the copy:

var myCars = MyCars.sharedInstance
println( myCars )
// the above prints all three cars
myCars.append("Gremlin")

Do the two variables point to different sets? Test:

println( MyCars.sharedInstance )
// the above prints three cars
println( myCars )
// the above prints four cars 

So, in a Playground environment you do not get a singleton using a struct with a static var. This is unfortunate, as it would otherwise be a very simple way to implement a singleton array. I'm having big difficulties with this problem. A partial solution has been spelled out in this post. In this solution you do get to reference the singleton using subscripts (so the singleton is somewhat array-like). But other array features (e.g. normal assignments) are missing. That is, you can't use the following:

MySingletonClass.sharedInstance = [ "Granada", "Pinto", "Chevette" ]

Note: I'm pretty new to Swift; the above assertions don't carry much authority. There are changes going from Swift 1.1 to Swift 1.2 in how singletons are defined and those changes are summarized here. The mechanism used by Swift 1.1 to define singletons is confusing, but Martin Rue has a very readable, step-by-step development spelled out here.

Good luck! - George

Community
  • 1
  • 1