2012-07-23 6 views
8

मैं एक ऐसा टूल लिख रहा हूं जो यह जानने से लाभ होगा कि किस वर्ग के आवृत्ति चर __weak घोषित किए गए हैं।रनटाइम पर डिस्कवर जो क्लास 'इंस्टेंस वेरिएबल्स घोषित किया जाता है __weak

यह जानकारी रनटाइम पर कहीं मौजूद होनी चाहिए, लेकिन क्या इसे एक्सेस करने, दस्तावेज करने या अन्यथा पहुंचने का कोई तरीका है? (यह एक उपकरण के लिए है, इसलिए मुझे अपडेट के साथ तोड़ने के बारे में बहुत परवाह नहीं है)

+0

इस प्रश्न ने मेरी कल्पना पकड़ी है, इसलिए यदि आपको कोई प्रतिक्रिया नहीं मिलती है, तो चिंता न करें, मैं इस पर काम कर रहा हूं –

+0

क्या इससे कोई फर्क पड़ता है कि iVar 'unsafe_unretained' बनाम 'कमजोर' है? यदि नहीं, तो यह मेरे जीवन को और अधिक आसान बनाता है। –

+0

मजबूत बनाम मजबूत नहीं है जिस भेद में मुझे रूचि है। –

उत्तर

4

ठीक है, यहां एक कस्टम ऑब्जेक्ट कार्यान्वयन का उपयोग करके एक नमूना कार्यान्वयन है, यह देखने के लिए एक प्राथमिक जांच करता है कि आईवीआर कमजोर है या नहीं या नहीं:

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; 
} 

उपरोक्त कोड, जबकि निम्न कस्टम वस्तु कोड नहीं है, एआरसी सक्षम साथ प्रयोग किया जा करने के लिए है:

@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 

कमजोर Ivars के लिए यह केवल काम करता है। unsafe_unretained चर के साथ, यह एक झूठा सकारात्मक देगा, इसके लिए मेरा सबसे अच्छा अनुमान है क्योंकि __weak जानकारी रनटाइम पर सहेजी जाती है जबकि unsafe_unretained जानकारी नहीं है।

मुझे आशा है कि इससे मदद मिलती है!

+0

दिलचस्प। मैंने सोचा था कि रनटाइम को केवल कमजोर संदर्भों को शून्य करने के लिए भंडारण के बारे में जानकारी की आवश्यकता होती है, लेकिन मैंने यह नहीं सोचा था कि object_setIvar को भी इसकी आवश्यकता होगी (हालांकि यह समझ में आता है कि object_setInstanceVariable एआरसी के तहत प्रतिबंधित है)। यह शायद '__unsafe_unretained' का इलाज' __weak' के समान होना चाहिए। मैं एक बग फाइल करूंगा। –

संबंधित मुद्दे