[swift-evolution] Argument of '#selector' cannot refer to a property?

Brent Royal-Gordon brent at architechies.com
Mon Feb 22 19:32:52 CST 2016


> 1) The compiler doesn’t accept #selector of properties with the error message: Argument of '#selector' cannot refer to a property. What’s the reasoning for that?

Because in Objective-C, a property is syntactic sugar for a pair of accessor methods, but in Swift, a property is a completely distinct entity from a method. 

> 2) Even if it did, I would still have the wrap #selector with NSStringFromSelector. It would be really convenient if Selector objects would convert to String. How is that possible?

It isn't appropriate. A selector is a different type from a string. Even Objective-C doesn't let you do this.

Basically, both of these are instances of you wanting vastly looser semantics. That's just not in Swift's nature.

A different way to approach this whole problem is to use strings instead of selectors for your field names, which allows you to use traditional Key-Value Coding:

	class Model: NSObject {
		dynamic var firstName: String = ""
		dynamic var lastName: String = ""
	}
	
	extension Model {
		static var jsonFields = ["firstName", "lastName"]
		
		var jsonValue: [String: AnyObject] {
			return dictionaryWithValuesForKeys(Model.jsonFields)
		}
	}

You could even protocolize it for reusability:

	protocol JSONRepresentable {
		static var jsonFields: [String] { get }
		var jsonValue: [String: AnyObject] { get }
	}
	
	extension JSONRepresentable where Self: NSObject {
		var jsonValue: [String: AnyObject] {
			return dictionaryWithValuesForKeys(Self.jsonFields)
		}
	}
	
	class Model: NSObject {
		dynamic var firstName: String = ""
		dynamic var lastName: String = ""
	}
	
	extension Model: JSONRepresentable {
		static var jsonFields = ["firstName", "lastName"]
	}

That solves both problems, though you lose the typo checking that #selector might provide.

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list