Skip to content

Instantly share code, notes, and snippets.

@steipete
Last active October 17, 2019 11:43
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save steipete/faf0c5e4dc79dfb3fc173b4e91475409 to your computer and use it in GitHub Desktop.
Save steipete/faf0c5e4dc79dfb3fc173b4e91475409 to your computer and use it in GitHub Desktop.
Helper to call target/action from an UIBarButtonItem.
#define PSCCAssert(condition, description, ...) \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wnullable-to-nonnull-conversion\"") \
NSCAssert(condition, description, ##__VA_ARGS__) \
_Pragma("clang diagnostic pop")
#define PSCWeakifyAs(object, weakName) typeof(object) __weak weakName = object
void (^psc_targetActionBlock(id target, SEL action))(id) {
// If there's no target, return an empty block.
if (!target) return ^(__unused id sender) {};
NSCParameterAssert(action);
// All ObjC methods have two arguments. This fails if either target is nil, action not implemented or else.
NSUInteger numberOfArguments = [target methodSignatureForSelector:action].numberOfArguments;
PSCCAssert(numberOfArguments == 2 || numberOfArguments == 3, @"%@ should have at most one argument.", NSStringFromSelector(action));
PSCWeakifyAs(target, weakTarget);
if (numberOfArguments == 2) {
return ^(__unused id sender) { PSC_SILENCE_CALL_TO_UNKNOWN_SELECTOR([weakTarget performSelector:action];) };
} else {
return ^(id sender) { PSC_SILENCE_CALL_TO_UNKNOWN_SELECTOR([weakTarget performSelector:action withObject:sender];) };
}
}
// Usage:
// psc_targetActionBlock(pdfController.outlineButtonItem.target, pdfController.outlineButtonItem.action)(nil);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment