0

I have:

var _feedbacks: [feedBack]!

I want to add a property to [feedBack] so that I could say :

var _ID = _feedBacks.ID 

I tried:

extension Array {   
    var ID: String {        
        get { 
            return self.ID
        }

        set {
            self.ID = newValue
        }
    }
}

But the compiler throws "EXC_BAD_ACCESS" when I tried to set/get ID

And I also tried:

import ObjectiveC

private var arrayAssocationKey: Void?

extension Array {
    var ID: String {
        get {
            return objc_getAssociatedObject(self, &arrayAssocationKey) as? String
        }
        set {
            objc_setAssociatedObject(self, &arrayAssocationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
        }
    }
}

But the compiler calls the error `Array does not conform to protocol AnyObject

Is there any workaround to set this property?

Antonio
  • 71,651
  • 11
  • 148
  • 165
Tinyik
  • 457
  • 6
  • 21

2 Answers2

1

Extending all arrays to add an ID property seems like overkill. I think you'd be better off creating a class that holds an ID and an array of feedback, something like this:

    class feedbackCollection {
        var ID: String?
        var feedbacks: [feedback]?
    }

EDIT:

A more generic attempt at this solution might be useful to you:

class IDArray<T> {
    var ID: String
    var items: [T]
    init(ID: String, items: [T]) {
        self.ID = ID
        self.items = items
    }
}

It would be used like this:

let ints = IDArray(ID: "1", items: [1, 2, 4])

let strings = IDArray(ID: "2", items: ["test", "this", "thing"])

strings.ID = "8"
strings.items.append("more")
Mike Taverne
  • 9,156
  • 2
  • 42
  • 58
0

What you are trying to do is adding a stored property, regardless of whether accessed using a computed property or directly exposed.

The ID property would be a new variable that you'd want to add to the Array type, but that's not possible. The array, as well as any other class, struct and enum, define their stored properties in the main declaration (not in an extension) so that it's possible to determine at compilation time the size of the memory occupied by an instance of that class/struct/enum.

Adding a stored property using an extension is not possible because that would change the memory size - an additional properties adds more bytes. The problem is that an extension can be visible in some places (for instance, in a framework), but invisible in other places (for instance, in another framework) - making the array incompatible with itself when used across different boundaries.

The computed property variant:

extension Array {   
    var ID: String {        
        get { 
            return self.ID
        }

        set {
            self.ID = newValue
        }
    }
}

cannot work: it is recursively referencing itself in the getter and setter implementation (see this answer)

I've never used associated objects (more for a philosophical reason: if I use it, it sounds like my code design is bad), but I think it should be used as follows:

private var arrayAssocationKey: String?

extension NSArray {
    var ID: String? {
        get {
            return objc_getAssociatedObject(self, &arrayAssocationKey) as? String
        }
        set {
            objc_setAssociatedObject(self, &arrayAssocationKey, newValue, objc_AssociationPolicy(OBJC_ASSOCIATION_COPY))
        }
    }
}

var array = NSArray()

array.ID = "5"
println(array.ID)
Community
  • 1
  • 1
Antonio
  • 71,651
  • 11
  • 148
  • 165