我有一个 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
断言总是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
请注意,基本操作类的消费者是 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
参数必须是 my 的子类BaseClass
?
编辑:
我意识到我发布的示例在将这些部分拉入单独的 Xcode 工作区后工作正常。我已经从上面发布了玩具源代码,但我在原始描述中没有提及。
我实际上有两个静态库(libSharedStuff.a
和libHelperSharedStuff.a
)。应用程序目标链接libSharedStuff.a
,单元测试目标取决于应用程序目标以及链接libHelperSharedStuff.a
。当BaseClass.m
是两个静态库目标的成员时+isSubclassOfClass:
,单元测试断言将失败。具体来说,当我通过时它会失败,这是单元测试目标MockBaseClass
的子类。BaseClass
所有这些都在上面链接的项目中进行了说明。