This is not required. +load guaranteed to be thread safe and repeatable. See load_images in objc-runtime-new.mm :
/*********************************************************************** * load_images * Process +load in the given images which are being mapped in by dyld. * Calls ABI-agnostic code after taking ABI-specific locks. * * Locking: write-locks runtimeLock and loadMethodLock **********************************************************************/ const char * load_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]) { BOOL found; recursive_mutex_lock(&loadMethodLock); // Discover load methods rwlock_write(&runtimeLock); found = load_images_nolock(state, infoCount, infoList); rwlock_unlock_write(&runtimeLock); // Call +load methods (without runtimeLock - re-entrant) if (found) { call_load_methods(); } recursive_mutex_unlock(&loadMethodLock); return nil; }
Pay attention to the recursive mutex, which ensures that all loads will be executed when it is blocked, and call_load_methods() will ensure that + loading is enabled only once to implement +load .
Please note that the +load feature is that there can be many implementations for each class, which is one of the reasons why he prefers swizzling - your +load , as well as the original +load guaranteed to be called.
Bonus: here is the relevant documentation for call_load_methods() , which directly addresses why it is thread safe, so that it is:
/*********************************************************************** * call_load_methods * Call all pending class and category +load methods. * Class +load methods are called superclass-first. * Category +load methods are not called until after the parent class +load. * * This method must be RE-ENTRANT, because a +load could trigger * more image mapping. In addition, the superclass-first ordering * must be preserved in the face of re-entrant calls. Therefore, * only the OUTERMOST call of this function will do anything, and * that call will handle all loadable classes, even those generated * while it was running. * * The sequence below preserves +load ordering in the face of * image loading during a +load, and make sure that no * +load method is forgotten because it was added during * a +load call. * Sequence: * 1. Repeatedly call class +loads until there aren't any more * 2. Call category +loads ONCE. * 3. Run more +loads if: * (a) there are more classes to load, OR * (b) there are some potential category +loads that have * still never been attempted. * Category +loads are only run once to ensure "parent class first" * ordering, even if a category +load triggers a new loadable class * and a new loadable category attached to that class. * * Locking: loadMethodLock must be held by the caller * All other locks must not be held. **********************************************************************/ void call_load_methods(void)
Richard J. Ross III
source share