NSOperation
クライアントが独自のロジックを追加するためにサブクラス化する必要がある基本クラスを定義する iOS 静的ライブラリがあります。@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 ワークスペースにプルした後、正常に動作することに気付きました。上記のおもちゃのソース コードを投稿しましたが、元の説明にはひねりが加えられていません。
私は実際に2 つの静的ライブラリ (libSharedStuff.a
とlibHelperSharedStuff.a
) を持っています。アプリケーション ターゲットは とリンクしlibSharedStuff.a
、単体テスト ターゲットはアプリケーション ターゲットとリンクに依存しますlibHelperSharedStuff.a
。が両方の静的ライブラリ ターゲットBaseClass.m
のメンバーである場合、単体テスト アサーションで失敗します。具体的には、単体テスト ターゲットの一部であるのサブクラスであるを渡すと失敗します。+isSubclassOfClass:
MockBaseClass
BaseClass
これらはすべて、上記のリンクされたプロジェクトに示されています。