1

I have a Swift project that contains two UITableViewControllers. The second UITableViewController is linked to a MVC model called Model. According to the UITableViewCell I select in the first UITableViewController, I want to initialize some properties of Model with Ints or Strings. Therefore, I've decided to define those properties with Printable protocol type. In the same time, I want to perform Key Value Observing on one of these properties.

Right now, Model looks like this:

class Model: NSObject {

    let title: String
    let array: [Printable]
    dynamic var selectedValue: Printable //error message

    init(title: String, array: [Printable], selectedValue: Printable) {
        self.title = title
        self.array = array
        self.selectedValue = selectedValue
    }

}

The problem here is that the following error message appears on the selectedValue declaration line:

Property cannot be marked dynamic because its type cannot be represented in Objective-C

If I go to the Xcode Issue Navigator, I can also read the following line:

Protocol 'Printable' is not '@objc'

Is there any workaround?

Imanou Petit
  • 89,880
  • 29
  • 256
  • 218
  • You're using KVO so you should look at it from the perspective of Objective-C. If this were Objective-C, how would you declare `selectedValue`? – newacct Oct 15 '14 at 21:42
  • Well, good question. I bet I would have use `id`... – Imanou Petit Oct 16 '14 at 14:31
  • Check this answer http://stackoverflow.com/questions/27319588/generic-function-and-attribute-with-equatable-and-printable-as-parameters-in-swi/27319612?noredirect=1#comment43099452_27319612 – Daniel Gomez Rico Dec 05 '14 at 18:44

2 Answers2

0

There is no way to do what you want. Non-@objc protocols cannot be represented in Objective-C. One reason is that Non-@objc protocols can represent non-class types (and indeed, you said that you wanted to use it for Int and String, both non-class types), and protocols in Objective-C are only for objects.

KVO is a feature designed for Objective-C, so you must think about what you expect it to see from the perspective of Objective-C. If you were doing this in Objective-C, you would not want to have a property that could either be an object like id or a non-object like int -- you can't even declare that. Instead, as you said in your comment, you probably want it to be just objects. And you want to be able to use Foundation's bridging to turn Int into NSNumber * and String into NSString *. These are regular Cocoa classes that inherit from NSObject, which implements Printable.

So it seems to me you should just use NSObject or NSObjectProtocol.

newacct
  • 119,665
  • 29
  • 163
  • 224
-1

Unfortunately ObjC does not treat protocols as types, they are just a convenient way of grouping members. Under the covers they are of type Any, so regretfully you will have to make the property Any and cast to Printable.

The best I can thing of is:

dynamic var selectedValue: Any
var printableValue : Printable {
  get {
    return (Printable)selectedValue
  }
  set {
    selectedValue = newValue
  }
} 
Howard Lovatt
  • 968
  • 1
  • 8
  • 15