'Objective-C selector with invalid characters?
When interfacing with the Objective-C runtime, it seems that selector names are allowed to have "illegal" characters. One can use this kind of selector to add new methods and call them in ways that would not be possible in code.
Let me give an example:
final class Test: NSObject {
@objc func test() {
print("This is Sparta!")
}
}
// Xcode indeed shows a warning "String literal is not a valid Objective-C selector"
let selector = Selector("invalid? !@#$%^&*()")
// let's add a new method, having the same implementation as an existing one
let testMethod = class_getInstanceMethod(Test.self, #selector(Test.test))!
let added = class_addMethod(Test.self, selector, method_getImplementation(testMethod), "v@:")
print("class_addMethod result: \(added)")
// let's see if calling the method works
Test().perform(selector)
The above code creates a selector with an invalid(?) name, uses the selector to add a new method to the test class, and calls that method afterward. Of course, one cannot directly call that method via the dot notation, as they would get a compiler error, however, the newly added method can be called via performSelector.
And to my surprise, the above code generates the following output:
class_addMethod result: true
This is Sparta!
This means that we can define, at runtime, methods with names that would generate compile errors if written in the class declaration.
I couldn't find any documentation supporting this behavior, intuitively since selector names are bare strings, dynamic method lookup should work with any kind of string.
Is this expected behavior? If yes, are there any limitations (except maybe length) on the contents of a selector name?
Solution 1:[1]
In Objetive-C's grammar @selector names are Identifiers
Identifiers An Objective-C identifier is a name used to identify a variable, function, or any other user-defined item. An identifier starts with a letter A to Z or a to z or an underscore _ followed by zero or more letters, underscores, and digits (0 to 9).
Objective-C does not allow punctuation characters such as @, $, and % within identifiers. Objective-C is a case-sensitive programming language. Thus, Manpower and manpower are two different identifiers in Objective-C. Here are some examples of acceptable identifiers:
myname50 _temp j a23b9 retVal
https://www.tutorialspoint.com/objective_c/objective_c_basic_syntax.htm
Is this expected behavior? If yes, are there any limitations (except maybe length) on the contents of a selector name?
I think it is expected, as the Obj-c runtime keeps a hash table of selectors anything that can be encoded in UTF-8 and hashed should work. I would not rely on this behavior, personally.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
