Skip to content

Instantly share code, notes, and snippets.

@saagarjha
Last active December 1, 2022 08:52
Show Gist options
  • Save saagarjha/e17775ec89794624e556e6eeee8ec857 to your computer and use it in GitHub Desktop.
Save saagarjha/e17775ec89794624e556e6eeee8ec857 to your computer and use it in GitHub Desktop.
Works around a hang in Xcode when it calls -[NSObject conformsToProtocol:] a bunch (https://twitter.com/_saagarjha/status/1476739462197506048)
// https://gist.github.com/saagarjha/ed701e3369639410b5d5303612964557
#import "swizzler.h"
#import <Foundation/Foundation.h>
#import <mutex>
#import <objc/runtime.h>
#import <unordered_map>
#import <utility>
struct PairHasher {
std::size_t operator()(const std::pair<Class, Protocol *> &pair) const {
// This sucks but it's good enough
return reinterpret_cast<uintptr_t>(pair.first) ^ reinterpret_cast<uintptr_t>(pair.second);
}
};
Swizzler<BOOL, NSObject *, Protocol *> NSObject_conformsToProtocol_ {
NSObject.class, @selector(conformsToProtocol:), [](auto self, auto protocol) {
static std::mutex mutex;
static std::unordered_map<std::pair<Class, Protocol *>, BOOL, PairHasher> conformanceCache;
auto pair = std::make_pair(self.class, protocol);
std::lock_guard<std::mutex> lock(mutex);
if (auto location = conformanceCache.find(pair); location != conformanceCache.end()) {
return location->second;
} else {
auto result = NSObject_conformsToProtocol_(self, protocol);
conformanceCache[pair] = result;
return result;
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment