クラスのインスタンス変数のどれが宣言されているかを知ることで恩恵を受けるツールを書いています__weak
。
この情報は実行時にどこかに存在する必要がありますが、文書化されているかどうかにかかわらず、それにアクセスする方法はありますか? (ツール用なのでアップデートで壊れてもあまり気にしません)
クラスのインスタンス変数のどれが宣言されているかを知ることで恩恵を受けるツールを書いています__weak
。
この情報は実行時にどこかに存在する必要がありますが、文書化されているかどうかにかかわらず、それにアクセスする方法はありますか? (ツール用なのでアップデートで壊れてもあまり気にしません)
では、カスタム オブジェクトの実装を使用して、iVar が弱いかどうかを確認するための基本的なチェックを行うサンプル実装を次に示します。
BOOL iVarIsWeak(Class cls, Ivar ivar)
{
id classInstance = [cls new];
// our custom base class properly tracks reference counting, no weird voodoo
id refCounter = [CustomBaseClass new];
object_setIvar(classInstance, ivar, refCounter);
if ([refCounter refCount] == 2)
{
return NO;
}
return YES;
}
上記のコードは ARC を有効にして使用することを意図していますが、次のカスタム オブジェクト コードはそうではありません。
@interface CustomBaseClass : NSObject
+(id) new;
+(id) alloc;
-(id) init;
-(id) retain;
-(void) release;
-(id) autorelease;
-(void) dealloc;
-(id) description;
-(unsigned) refCount;
@end
// easy way to get sizeof
struct CustomBaseClassAsStruct {
voidPtr isa;
unsigned volatile refcount;
};
@implementation CustomBaseClass
{
unsigned volatile refcount;
}
+(id) new
{
return [[self alloc] init];
}
+(id) alloc
{
struct CustomBaseClassAsStruct *results = malloc(sizeof(struct CustomBaseClassAsStruct));
results->isa = self;
results->refcount = 0;
return (id) results;
}
-(id) init
{
[self retain];
return self;
}
-(id) retain
{
++refcount;
return self;
}
-(void) release
{
if (--refcount == 0)
[self dealloc];
}
-(id) autorelease
{
// sample implementation of autorelease
dispatch_async(dispatch_get_current_queue(), ^{
[self release];
});
return self;
}
-(unsigned) refCount
{
return refcount;
}
-(void) dealloc
{
free(self);
// no call to [super dealloc], we are using custom memory-managment
}
@end
これは、弱い iVar に対してのみ機能します。変数を使用unsafe_unretained
すると、誤検知が発生します。これについての私の最良の推測は、__weak
情報は実行時に保存されますが、情報は保存されunsafe_unretained
ないためです。
これが役立つことを願っています!