我有一个 iOS 静态库,它定义了一个
NSOperation
基类,客户端应该将其子类化以将他们自己的逻辑添加到:@interface BaseClass : NSOperation
/p>客户端向管理器注册它们的子类:
-[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
断言总是NO
,即使传递给BaseClass
。
在类(class)层次结构中走得更高怎么样? 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
请注意,基本操作类的使用者是 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
在应用目标中
@interface OutsideClass : NSOperation
@end
@interface OutsideClassSubA : OutsideClass
@end
... 传入 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
这是怎么回事?为什么 +isSubclassOfClass:
给出了错误的答案?如何强制 aClass
参数必须是我的 BaseClass
的子类?
编辑:
我意识到我发布的示例在将这些部分拉入单独的 Xcode 工作区后工作正常。我有 posted the toy source code from above我省略了原来的描述。
我实际上有两个静态库(libSharedStuff.a
和libHelperSharedStuff.a
)。应用程序目标链接到 libSharedStuff.a
,单元测试目标取决于应用程序目标以及链接 libHelperSharedStuff.a
。当 BaseClass.m
是两个 静态库目标的成员时,+isSubclassOfClass:
将在单元测试断言中失败。具体来说,当我通过 MockBaseClass
时失败,它是 BaseClass
的子类,是单元测试目标的一部分。
所有这些都在上面链接的项目中进行了说明。
最佳答案
正如我在编辑问题时所解释的,我在两个静态库 libSharedStuff.a
和 libHelperSharedStuff.a中都包含了
。主要应用程序目标链接到 BaseClass.m
libSharedStuff.a
,单元测试目标链接到 libHelperSharedStuff.a
。这意味着当 .xctest
包在运行时被注入(inject)我的应用程序时,BaseClass
符号被定义了两次
(也许?这可能吗?运行时实际发生了什么?)。
我似乎在我的单元测试目标中 MockSubclassOfBaseClass
继承自 libHelperSharedStuff.a
中的 BaseClass
符号,而在我的应用程序目标中 SubclassOfBaseClass
继承自libSharedStuff.a
中的BaseClass
符号。如果是这样,那么当传入 MockSubclassOfBaseClass
时,+isSublcassOfClass:
响应 NO
的原因就有意义了!
非常感谢任何澄清、确认或提供我的正确想法的更好见解的答案。
关于ios - ObjC : +[NSObject isSubclassOfClass:] gives incorrect failure,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19883472/