Skip to content

Instantly share code, notes, and snippets.

@nerdo
Forked from cprovatas/BlockBasedSelector.h
Created February 9, 2018 23:24
Show Gist options
  • Save nerdo/e0cdc89aad27fbb43d98b21e8ef80c65 to your computer and use it in GitHub Desktop.
Save nerdo/e0cdc89aad27fbb43d98b21e8ef80c65 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 PPSelector);
typedef void (^OBJCBlockWithSender)(id PPSelector, 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 Passport Parking. All rights reserved.
//
import Foundation
import UIKit
// swiftlint:disable identifier_name
func Selector(_ block: @escaping () -> Void) -> Selector {
let selector = NSSelectorFromString("\(CACurrentMediaTime())")
class_addMethodWithBlock(PPSelector.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("\(CACurrentMediaTime())")
class_addMethodWithBlockAndSender(PPSelector.self, selector) { (_, sender) in block(sender) }
return selector
}
// swiftlint:disable identifier_name
let Selector = PPSelector.shared
@objc class PPSelector: NSObject {
static let shared = PPSelector()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment