Skip to content

Instantly share code, notes, and snippets.

@brentsimmons
Last active August 29, 2015 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brentsimmons/71281261478c39adcd3b to your computer and use it in GitHub Desktop.
Save brentsimmons/71281261478c39adcd3b to your computer and use it in GitHub Desktop.
Protocols and pointer equality
//: Playground - noun: a place where people can play
import Cocoa
// Solution: if I use "class" instead of "AnyObject", then it’s a pure Swift solution:
// http://inessential.com/2015/07/23/swift_diary_3_arrays_protocols_and_p
// https://twitter.com/_mattrubin/status/624266521896992768
// Or… AnyObject may be marked @objc, but it is in fact a native Swift feature:
// https://twitter.com/jckarter/status/624270700614942721
protocol NodeRepresentedObject: AnyObject {
var localizedName: String {get set}
}
class File: NodeRepresentedObject, CustomStringConvertible {
var localizedName: String
let fileID: Int
var description: String {
get {
return "File: \(fileID) \"\(localizedName)\""
}
}
init(fileID: Int, localizedName: String) {
self.localizedName = localizedName
self.fileID = fileID
}
}
class Folder: NodeRepresentedObject, CustomStringConvertible {
var localizedName: String
let folderID: String
var description: String {
get {
return "Folder: \(folderID) \"\(localizedName)\""
}
}
init(folderID: String, localizedName: String) {
self.localizedName = localizedName
self.folderID = folderID
}
}
class Node: CustomStringConvertible {
var children = [Node]()
var representedObject: NodeRepresentedObject
var description: String {
get {
return "Node: representedObject: \(representedObject)"
}
}
init(_ representedObject: NodeRepresentedObject) {
self.representedObject = representedObject
}
func addChildWithRepresentedObject(representedObject: NodeRepresentedObject) {
if existingChildWithRepresentedObject(representedObject) == nil {
children += [Node(representedObject)]
}
}
func existingChildWithRepresentedObject(representedObjectToFind: NodeRepresentedObject) -> Node? {
for oneChild in children {
if oneChild.representedObject === representedObjectToFind {
return oneChild
}
}
return nil
}
}
var topLevelFolder = Folder(folderID: "top", localizedName: "Top")
var topLevelNode = Node(topLevelFolder)
var subFolder = Folder(folderID: "subfolder", localizedName: "Sub Folder")
var subFile = File(fileID: 1, localizedName: "A File")
topLevelNode.addChildWithRepresentedObject(subFolder)
topLevelNode.addChildWithRepresentedObject(subFile)
print(topLevelNode.children)
topLevelNode.children.count //Should be 2
// Should not actually add subFile again.
topLevelNode.addChildWithRepresentedObject(subFile)
print(topLevelNode.children)
topLevelNode.children.count //Should still be 2
@beno
Copy link

beno commented Jul 24, 2015

Why all the wrappers? Here's my (much simpler) take on this:

https://gist.github.com/beno/d5e57d872157485dace1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment