macro_rules! sel { (alloc) => { ... }; (init) => { ... }; (new) => { ... }; ($first:ident $(: $($rest:ident :)*)?) => { ... }; }
Expand description
Register a selector with the Objective-C runtime.
Returns the Sel
corresponding to the specified selector.
Panics
Panics if the runtime failed allocating space for the selector.
Specification
This has similar syntax and functionality as the @selector
directive in
Objective-C.
This calls Sel::register
internally. The result is cached for
efficiency. The cache for certain common selectors (alloc
, init
and
new
) is deduplicated to reduce code-size.
Non-ascii identifiers are ill-tested, if supported at all.
Features
If the experimental "unstable-static-sel"
feature is enabled, this will
emit special statics that will be replaced by the dynamic linker (dyld)
when the program starts up - in exactly the same manner as normal
Objective-C code does.
This should be significantly faster (and allow better native debugging),
however due to the Rust compilation model, and since we don’t have
low-level control over it, it is currently unlikely that this will work
correctly in all cases.
See the source code and rust-lang/rust#53929 for more info.
Concretely, this may fail at:
- link-time (likely)
- dynamic link-time/just before the program is run (fairly likely)
- runtime, causing UB (unlikely)
The "unstable-static-sel-inlined"
feature is the even more extreme
version - it yields the best performance and is closest to real
Objective-C code, but probably won’t work unless your code and its
inlining is written in a very certain way.
Enabling LTO greatly increases the chance that these features work.
Examples
Get a few different selectors:
use objc2::sel;
let sel = sel!(alloc);
let sel = sel!(description);
let sel = sel!(_privateMethod);
let sel = sel!(storyboardWithName:bundle:);
let sel = sel!(
otherEventWithType:
location:
modifierFlags:
timestamp:
windowNumber:
context:
subtype:
data1:
data2:
);
Whitespace is ignored:
let sel1 = sel!(setObject:forKey:);
let sel2 = sel!( setObject :
forKey : );
assert_eq!(sel1, sel2);
Invalid selector:
let sel = sel!(aSelector:withoutTrailingColon);
Unsupported usage that you may run into when using macros - fails to
compile when the "unstable-static-sel"
feature is enabled.
Instead, define a wrapper function that retrieves the selector.
use objc2::sel;
macro_rules! x {
($x:ident) => {
// One of these is fine
sel!($x);
// But using the identifier again in the same way is not!
sel!($x);
};
}
// Identifier `abc`
x!(abc);