Skip to content

Instantly share code, notes, and snippets.

@kebbbnnn
Forked from cprovatas/BlockBasedSelector.h
Created September 25, 2020 12:48
Show Gist options
  • Save kebbbnnn/2104bb9d8f5d9961d84a6607430d9956 to your computer and use it in GitHub Desktop.
Save kebbbnnn/2104bb9d8f5d9961d84a6607430d9956 to your computer and use it in GitHub Desktop.
Block-Based Selectors in Swift
//
// BlockBasedSelector.h
//
// Created by Charlton Provatas on 11/2/17.
// Copyright © 2017 CharltonProvatas. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface BlockBasedSelector : NSObject
@end
typedef void (^OBJCBlock)(id _Selector);
typedef void (^OBJCBlockWithSender)(id _Selector, id sender);
void class_addMethodWithBlock(Class class, SEL newSelector, OBJCBlock block);
void class_addMethodWithBlockAndSender(Class class, SEL newSelector, OBJCBlockWithSender block);
//
// BlockBasedSelector.m
//
// Created by Charlton Provatas on 11/2/17.
// Copyright © 2017 CharltonProvatas. All rights reserved.
//
#import "BlockBasedSelector.h"
#import <objc/runtime.h>
@implementation BlockBasedSelector
@end
void class_addMethodWithBlock(Class class, SEL newSelector, OBJCBlock block)
{
IMP newImplementation = imp_implementationWithBlock(block);
Method method = class_getInstanceMethod(class, newSelector);
class_addMethod(class, newSelector, newImplementation, method_getTypeEncoding(method));
}
void class_addMethodWithBlockAndSender(Class class, SEL newSelector, OBJCBlockWithSender block)
{
IMP newImplementation = imp_implementationWithBlock(block);
Method method = class_getInstanceMethod(class, newSelector);
class_addMethod(class, newSelector, newImplementation, method_getTypeEncoding(method));
}
//
// BlockBasedSelector.swift
// Parking
//
// Created by Charlton Provatas on 11/9/17.
// Copyright © 2017 Charlton Provatas. All rights reserved.
//
import Foundation
// swiftlint:disable identifier_name
func Selector(_ block: @escaping () -> Void) -> Selector {
let selector = NSSelectorFromString("\(CFAbsoluteTimeGetCurrent())")
class_addMethodWithBlock(_Selector.self, selector) { _ in block() }
return selector
}
/// used w/ callback if you need to get sender argument
func Selector(_ block: @escaping (Any?) -> Void) -> Selector {
let selector = NSSelectorFromString("\(CFAbsoluteTimeGetCurrent())")
class_addMethodWithBlockAndSender(_Selector.self, selector) { (_, sender) in block(sender) }
return selector
}
// swiftlint:disable identifier_name
let Selector = _Selector.shared
@objc class _Selector: NSObject {
static let shared = _Selector()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment