Search code examples
cocoaswiftnsset

Create unique-member collections in Swift


I don't see any way of guaranteeing uniqueness of the members of a Swift array/collection like Cocoa NSSets. If this is true, then I wonder what else is missing from Swift, vs Cocoa?

What am I missing, if anything?


Solution

  • What you're missing is that NSSet and the rest of Foundation, Cocoa, etc. is still there and always will be.

    EDIT: In Swift 1.2, Set is a native Swift type and you'll use that instead.

    There's absolutely nothing wrong with using NSSet when you need to. Here's an example from my own code:

    class TracksViewController : UITableViewController {
        // ...
        var observers = NSMutableSet()
        // ...
        override func viewDidLayoutSubviews() {
            func noteNowPlayingItem (note:NSNotification?) {
                // ...
            }
            // do it now!
            noteNowPlayingItem(nil)
            // and do it later, when now playing item notification arrives
            let ob = NSNotificationCenter.defaultCenter().addObserverForName(MPMusicPlayerControllerNowPlayingItemDidChangeNotification, 
                object: nil, queue: NSOperationQueue.mainQueue(), 
                usingBlock: noteNowPlayingItem)
            self.observers.addObject(ob)
        }
        // ...
    }
    

    So there I am using an NSMutableSet as a way of storing notification observers so I can do memory management later. No problem.

    Notice, however, that just in that little snippet of code I am taking advantage of Swift features that put it head and shoulders above Objective-C in my opinion:

    • The NSMutableSet property does not have to be initialized in code (e.g. in an initializer, or in viewDidLoad); I do it right when I declare it. You can't do that in Objective-C. So this is safe; this property will never accidentally be nil (has that ever happened to you??).

    • I use function-in-function, so that I can both call a closure and pass it. Yes, you can do the same thing in Objective-C (give a block a name), but is this syntax easier or what? I had to look up the "named closure" syntax every time I used it; now I spend my time writing code, not looking up obscure syntax that I can't write or read.

    Indeed, just sticking with arrays for a moment, there are lots of times when you have a Swift Array but you need to cast it to an NSArray, or pass an Array into a Cocoa method that takes an NSArray, so as to call some Foundation method that has no Swift equivalent. It's not a problem.