我有一个 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
所有这些都在上面链接的项目中进行了说明。