Objective-C报getExportedModule相关selector错误如何解决
错误原因
这两个报错是因为你错误调用了UMModuleRegistry的实例方法:你当前直接用类名UMModuleRegistry调用类方法,但getExportedModuleForName:、getAllExportedModules都是实例方法,需要用已注入的实例对象调用。另外你现有setModuleRegistry方法的赋值逻辑错误,根本没把传入的模块注册表存到属性里,导致你的ModuleRegistry属性一直为空。
修复步骤
- 修正
setModuleRegistry方法的赋值逻辑,将传入的模块注册表实例存入类的属性 - 把所有
[UMModuleRegistry 类方法调用]的代码,替换为[self.ModuleRegistry 实例方法调用]
完整修复后代码
#import <UMReactNativeAdapter/UMReactNativeEventEmitter.h> #import <UMCore/UMEventEmitter.h> #import <UMCore/UMExportedModule.h> #import <UMCore/UMModuleRegistry.h> @interface UMReactNativeEventEmitter () @property (nonatomic, assign) int listenersCount; @property (nonatomic, weak) UMModuleRegistry *ModuleRegistry; @property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *modulesListenersCounts; @end @implementation UMReactNativeEventEmitter - (instancetype)init { if (self = [super init]) { _listenersCount = 0; _modulesListenersCounts = [NSMutableDictionary dictionary]; } return self; } UM_REGISTER_MODULE(); + (NSString *)moduleName { return @"UMReactNativeEventEmitter"; } + (const NSArray<Protocol *> *)exportedInterfaces { return @[@protocol(UMEventEmitterService)]; } - (NSArray<NSString *> *)supportedEvents { NSMutableSet<NSString *> *eventsAccumulator = [NSMutableSet set]; // 已修改:用实例属性调用实例方法 for (UMExportedModule *exportedModule in [self.ModuleRegistry getAllExportedModules]) { if ([exportedModule conformsToProtocol:@protocol(UMEventEmitter)]) { id<UMEventEmitter> eventEmitter = (id<UMEventEmitter>)exportedModule; [eventsAccumulator addObjectsFromArray:[eventEmitter supportedEvents]]; } } return [eventsAccumulator allObjects]; } RCT_EXPORT_METHOD(addProxiedListener:(NSString *)moduleName eventName:(NSString *)eventName) { [self addListener:eventName]; // Validate module // 已修改:用实例属性调用实例方法 UMExportedModule *module = [self.ModuleRegistry getExportedModuleForName:moduleName]; if (RCT_DEBUG && module == nil) { UMLogError(@"Module for name `%@` has not been found.", moduleName); return; } else if (RCT_DEBUG && ![module conformsToProtocol:@protocol(UMEventEmitter)]) { UMLogError(@"Module `%@` is not an UMEventEmitter, thus it cannot be subscribed to.", moduleName); return; } // Validate eventEmitter id<UMEventEmitter> eventEmitter = (id<UMEventEmitter>)module; if (RCT_DEBUG && ![[eventEmitter supportedEvents] containsObject:eventName]) { UMLogError(@"`%@` is not a supported event type for %@. Supported events are: `%@`", eventName, moduleName, [[eventEmitter supportedEvents] componentsJoinedByString:@"`, `"]); } // Global observing state _listenersCount += 1; if (_listenersCount == 1) { [self startObserving]; } // Per-module observing state int newModuleListenersCount = [self moduleListenersCountFor:moduleName] + 1; if (newModuleListenersCount == 1) { [eventEmitter startObserving]; } _modulesListenersCounts[moduleName] = [NSNumber numberWithInt:newModuleListenersCount]; } RCT_EXPORT_METHOD(removeProxiedListeners:(NSString *)moduleName count:(double)count) { [self removeListeners:count]; // Validate module // 已修改:用实例属性调用实例方法 UMExportedModule *module = [self.ModuleRegistry getExportedModuleForName:moduleName]; if (RCT_DEBUG && module == nil) { UMLogError(@"Module for name `%@` has not been found.", moduleName); return; } else if (RCT_DEBUG && ![module conformsToProtocol:@protocol(UMEventEmitter)]) { UMLogError(@"Module `%@` is not an UMEventEmitter, thus it cannot be subscribed to.", moduleName); return; } id<UMEventEmitter> eventEmitter = (id<UMEventEmitter>)module; // Per-module observing state int newModuleListenersCount = [self moduleListenersCountFor:moduleName] - 1; if (newModuleListenersCount == 0) { [eventEmitter stopObserving]; } else if (newModuleListenersCount < 0) { UMLogError(@"Attempted to remove more `%@` listeners than added", moduleName); newModuleListenersCount = 0; } _modulesListenersCounts[moduleName] = [NSNumber numberWithInt:newModuleListenersCount]; // Global observing state if (_listenersCount - 1 < 0) { UMLogError(@"Attempted to remove more proxied event emitter listeners than added"); _listenersCount = 0; } else { _listenersCount -= 1; } if (_listenersCount == 0) { [self stopObserving]; } } # pragma mark Utilities - (int)moduleListenersCountFor:(NSString *)moduleName { NSNumber *moduleListenersCountNumber = _modulesListenersCounts[moduleName]; int moduleListenersCount = 0; if (moduleListenersCountNumber != nil) { moduleListenersCount = [moduleListenersCountNumber intValue]; } return moduleListenersCount; } # pragma mark - UMModuleRegistryConsumer - (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry { // 已修改:给实例属性赋值,不再错误给局部变量赋值 _ModuleRegistry = moduleRegistry; } @end
修改点汇总
- 修正
setModuleRegistry方法的赋值逻辑,将传入的模块注册表实例存入实例属性 - 共3处方法调用修改:
supportedEvents方法里的getAllExportedModules、addProxiedListener里的getExportedModuleForName、removeProxiedListeners里的getExportedModuleForName,全部从类方法调用改为实例方法调用
内容的提问来源于stack exchange,提问作者displayName
相关产品推荐
相关产品推荐

