【问题标题】:Discovering at runtime which of a class' instance variables are declared __weak在运行时发现哪个类的实例变量被声明为 __weak
【发布时间】:2012-07-22 04:34:11
【问题描述】:

我正在编写一个工具,该工具将受益于知道哪些类的实例变量被声明为__weak

此信息必须在运行时某处存在,但是有没有任何方法可以访问它,文档化或其他方式? (它是一个工具,所以我不太关心它是否会因更新而中断)

【问题讨论】:

  • 这个问题引起了我的注意,所以如果你没有得到回复,别担心,我正在努力解决
  • iVar 是 unsafe_unretained 还是 weak 是否重要?如果没有,那会让我的生活更轻松。
  • 强与不强是我感兴趣的区别。
  • 太棒了。然后给我 5-10 分钟的时间来拼凑一个答案,你会很成功的!
  • 好的,新的更新。可以在weakstrong 之间进行判断,但无论出于何种原因,__unsafe_unretained 似乎表现得像strong。需要更多时间。

标签: objective-c cocoa-touch cocoa automatic-ref-counting


【解决方案1】:

好的,这是一个示例实现,使用自定义对象实现,它会进行基本检查以查看 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 信息则不会。

我希望这会有所帮助!

【讨论】:

  • 有趣。我认为运行时只需要有关存储的信息,以便在解除分配时将弱引用归零,但我没有认为 object_setIvar 也需要它(尽管考虑到 object_setInstanceVariable 在 ARC 下被禁止,这是有道理的)。它可能应该像对待__weak 一样对待__unsafe_unretained。我会提交一个错误。
猜你喜欢
  • 2015-02-03
  • 2014-01-06
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 2014-03-04
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
相关资源
最近更新 更多