我有一个iOS静态库,它定义了一个NSOperation客户端应该子类化的基类,以便将自己的逻辑添加到:@interface BaseClass : NSOperation
客户端向经理注册其子类: -[OperationManagerClass registerClass:forType:]
在经理中,我想强制你必须注册一个BaseClass不仅仅是的子类NSOperation
好吧,似乎断言+isSubclassOfClass:应该完成工作.但是......事实并非如此.
@implementation OperationManagerClass
- (void)registerClass:(Class)aClass forType:(NSString *)type
{
NSAssert([aClass isSubclassOfClass:[BaseClass class]);
self.registeredClasses[type] = aClass;
}
@end
Run Code Online (Sandbox Code Playgroud)
NO即使通过,断言总是如此BaseClass.
如何在班级层级中走得更远?NSOperation并且NSObject都回应YES!
(lldb) p (BOOL)[aClass isSubclassOfClass:[BaseClass class]]
(BOOL) $0 = NO
(lldb) po aClass
BaseClass
(lldb) p (BOOL)[aClass isSubclassOfClass:[NSOperation class]]
(BOOL) $2 = YES
(lldb) p (BOOL)[aClass isSubclassOfClass:[NSObject class]]
(BOOL) $3 = YES
Run Code Online (Sandbox Code Playgroud)
你要知道,基础操作类的消费者在iOS的应用程序项目继承,并OperationManagerClass与BaseClass处于包括静态库.为什么我认为这可能与isSubclassOfClass:错误有关?由于以下原因......
还在libSharedStuff.a中
@implementation OperationManagerClass
- (void)registerClass:(Class)aClass forType:(NSString *)type
{
// Obviously OperationManagerClass.m cannot #import "OutsideClass.h"
NSAssert([aClass isSubclassOfClass:NSClassFromString(@"OutsideClass");
self.registeredClasses[type] = aClass;
}
@end
Run Code Online (Sandbox Code Playgroud)
在应用目标中
@interface OutsideClass : NSOperation
@end
@interface OutsideClassSubA : OutsideClass
@end
Run Code Online (Sandbox Code Playgroud)
... OutsideClassSubA传入时产生以下结果:
(lldb) p (BOOL)[aClass isSubclassOfClass:[OutsideClass class]]
(BOOL) $0 = YES
(lldb) po aClass
OutsideClassSubA
(lldb) p (BOOL)[aClass isSubclassOfClass:[NSOperation class]]
(BOOL) $2 = YES
(lldb) p (BOOL)[aClass isSubclassOfClass:[NSObject class]]
(BOOL) $3 = YES
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?为什么+isSubclassOfClass:给出错误的答案?如何强制aClass参数必须是我的子类BaseClass?
我实际上有两个静态库(libSharedStuff.a和libHelperSharedStuff.a).应用程序目标链接libSharedStuff.a,单元测试目标取决于应用程序目标以及链接libHelperSharedStuff.a.如果BaseClass.m是两个静态库目标的成员,则+isSubclassOfClass:单元测试断言将失败.具体来说,它在我通过时失败MockBaseClass,它是BaseClass单元测试目标的一部分.
所有这些都在上面链接的项目中说明.
正如我在编辑我的问题时所解释的那样,我包含BaseClass.m在静态库libSharedStuff.a和libHelperSharedStuff.a.主应用程序目标链接libSharedStuff.a与单元测试目标链接libHelperSharedStuff.a.这意味着当.xctest捆绑包在运行时注入我的应用程序时,BaseClass符号定义两次
(也许?这可能吗?运行时实际发生了什么?).
我似乎在我的单元测试目标中MockSubclassOfBaseClass继承了BaseClass符号libHelperSharedStuff.a,而在我的应用程序中,目标SubclassOfBaseClass继承自BaseClass符号libSharedStuff.a.如果是这种情况,那么为什么传入时会+isSublcassOfClass:响应!NOMockSubclassOfBaseClass
任何澄清,确认或提供更好的见解的答案都非常感谢我在这里得到了正确的想法.