2012-04-25 11 views
7

MyClass.h:कक्षा विस्तार में घोषित चर का उपयोग कैसे करते हैं?

@interface MyClass : NSObject 
@end 

MyClass.m:

// Define a private variable in a class extension 
@interface MyClass() { 
    NSString *name; 
} 
@end 
फिर बाद में

lldb में:

(lldb) po myClassInstance->name 
error: 'MyClass' does not have a member named 'name' 
error: 1 errors parsing expression 

तो आपको कैसे उपयोग करते हैं कि में चर डिबगर?

xcode 4.3.2

धन्यवाद!

उत्तर

-1

यदि आपको MyClass विधियों के बाहर से name तक पहुंचने की आवश्यकता है, तो आपको इसे एक्सेस करने के तरीकों को परिभाषित करने की आवश्यकता है। आप (NSString*) name और - (void) setName:(NSString*) newName नामक विधियों को लिख सकते हैं, लेकिन गुणों को परिभाषित करना और उन्हें संश्लेषित करना आसान है।

MyClass.h में, आप एक संपत्ति को परिभाषित करते हैं। तार के लिए, आप आमतौर पर उन्हें copy बनाने:

@interface MyClass : NSObject 

@property (copy) NSString* name; 

@end 

में MyClass.m, आप अभी भी अपने इंटरफेस घोषणा, इवर साथ उपयोग करें:

@interface MyClass() { 
    NSString *name; 
} 
@end 

हालांकि, अगर आप भी के संश्लेषण के लिए की जरूरत आपकी नई संपत्ति यह पुन: प्राप्त करने और नाम स्थापित करने के लिए तरीकों बनाता है:

@implementation MyClass 

@synthesize name = name; 

@end 

एक सम्मेलन के रूप में, यह प्रारंभ या इवर के अंत में एक अंडरस्कोर डाल करने के लिए है, इसलिए इंटरफ़ेस में आप NSString *_name; होता आम है, और में कार्यान्वयन आपके पास @synthesize name = _name होगा। जब आप संपत्ति का मतलब रखते हैं तो यह गलती से इवर का उपयोग करने से बचने में मदद करता है।

अब आप अपने नाम संपत्ति का उपयोग कर सकते हैं:

MyClass me = [[[MyClass alloc] init] autorelease]; 
[me setName:@"My name"]; 
NSLog(@"Name = %@", [me name]); 

ऑब्जेक्टिव-सी गुण भाषा का एक शक्तिशाली सुविधा हैं, लेकिन वे कुछ quirks आप सीखना चाहिए है। "उद्देश्य-सी", "गुण" और "संश्लेषण" के कुछ संयोजन के लिए वेब खोज आज़माएं।

यदि आपके पास अभी भी कंपाइलर त्रुटियां हैं, तो कृपया अपने कोड के हिस्से के साथ अपना प्रश्न संपादित करें जहां आप name एक्सेस करते हैं।

+0

ओपी डीबगर में चर का उपयोग करने के तरीके के बारे में पूछ रहा है। इसे संकलित करने के लिए कैसे नहीं मिलता है। मेरे साथ भी वही दिक्कत है। यह जवाब सहायक नहीं है। – rrrus

6

(lldb) po [myClassInstance valueForKey:@"name"]

+0

अच्छा, यह काम करता है, लेकिन यह निश्चित रूप से एक बदसूरत कामकाज है। – rrrus

+0

@rrrus हाँ, लेकिन यह रनटाइम का उपयोग करता है, यह 'गतिशील 'गुणों के लिए भी काम करेगा, यानी। कोर डेटा .. –

+0

यदि आप जो खोज रहे हैं वह काम नहीं करता है, यह एक ivar है और संपत्ति नहीं है। – AriX

0

सफाई से इन उदाहरण चर सीधे उपयोग करने के लिए एक ही रास्ता ऑब्जेक्टिव-सी क्रम है, जो उपयोगी समारोह object_getInstanceVariable प्रदान करता है के माध्यम से है। मान संदर्भ द्वारा वापस पारित किया जाता है, और कई अलग-अलग प्रकार हो सकते हैं, इसलिए यह डीबगर से बहुत उपयोगी नहीं है। लेकिन आपके प्रश्न ने मुझे समाधान के साथ आने के लिए प्रेरित किया।

मैंने एनएसओब्जेक्ट पर एक श्रेणी लिखी है जो आपको डिबगर से इंस्टेंस वैरिएबल को आत्मनिरीक्षण करने की इजाजत देता है, बिना एक्सेसर साइड इफेक्ट्स के बारे में चिंता किए। अपनी परियोजना के लिए श्रेणी जोड़ने के बाद, आप यह कर सकते हैं:

NSObject + IvarIntrospection.h

#if DEBUG 
#import <Foundation/Foundation.h> 

@interface NSObject (IvarIntrospection) 

- (id)valueOfInstanceVariable:(NSString *)ivarName; 

@end 

#endif 

NSObject + IvarIntrospection.m

#if DEBUG 
#import "NSObject+IvarIntrospection.h" 
#import <objc/runtime.h> 

@implementation NSObject (IvarIntrospection) 

- (id)valueOfInstanceVariable:(NSString *)ivarName { 
    // Get the value of the instance variable 
    // Use a union in order to convert the value to a float or double (see http://en.wikipedia.org/wiki/Type_punning) 
    union { 
     void *value; 
     float f; 
     double d; 
    } ivar; 
    Ivar ivarInfo = object_getInstanceVariable(self, [ivarName UTF8String], &ivar.value); 

    // If the instance variable doesn't exist, try adding an underscore 
    if (!ivarInfo && ![ivarName hasPrefix:@"_"]) { 
     NSString *underscoredIvarName = [@"_" stringByAppendingString:ivarName]; 
     NSLog(@"Instance variable '%@' does not exist. Perhaps you meant '%@?' Let's try that.", ivarName, underscoredIvarName); 

     return [self valueOfInstanceVariable:underscoredIvarName]; 

    // If there's already an underscore, error 
    } else if (!ivarInfo) { 
     NSLog(@"Instance variable '%@' does not exist.", ivarName); 
     return nil; 
    } 

    // Figure out what type the instance variable is and return a sensible representation 
    const char *type = ivar_getTypeEncoding(ivarInfo); 
    switch (type[0]) { 
     case 'c': 
      return [NSNumber numberWithChar:(char)ivar.value]; 
     case 'i': 
      return [NSNumber numberWithInt:(int)ivar.value]; 
     case 's': 
      return [NSNumber numberWithShort:(short)ivar.value]; 
     case 'l': 
      return [NSNumber numberWithLong:(long)ivar.value]; 
     case 'q': 
      return [NSNumber numberWithLongLong:(long long)ivar.value]; 
     case 'C': 
      return [NSNumber numberWithUnsignedChar:(unsigned char)ivar.value]; 
     case 'I': 
      return [NSNumber numberWithUnsignedInt:(unsigned int)ivar.value]; 
     case 'S': 
      return [NSNumber numberWithUnsignedShort:(unsigned short)ivar.value]; 
     case 'L': 
      return [NSNumber numberWithUnsignedLong:(unsigned long)ivar.value]; 
     case 'Q': 
      return [NSNumber numberWithUnsignedLongLong:(unsigned long long)ivar.value]; 
     case 'f': 
      return [NSNumber numberWithFloat:ivar.f]; 
     case 'd': 
      return [NSNumber numberWithDouble:ivar.d]; 
     case '*': 
      return [NSString stringWithUTF8String:(const char *)ivar.value]; 
     case '@': 
     case '#': 
      return (id)ivar.value; 
     case ':': 
      return NSStringFromSelector((SEL)ivar.value); 
     default: 
      return [NSValue valueWithBytes:&ivar.value objCType:type]; 
    } 
} 

@end 

#endif 
:

(lldb) po [self valueOfInstanceVariable:@"_name"] 
IMG_4078.PNG 

कोड यह

ध्यान दें कि रिलीज के लिए संकलन करते समय श्रेणी स्वचालित रूप से अक्षम हो जाएगी (डेब्यू के लिए धन्यवाद जी मैक्रो)।

+0

यदि आप इसे NSObject की श्रेणी बनाना चाहते हैं ... ठीक है लेकिन यह डीबगर में कुछ मानों को देखने के लिए थोड़ा भारी हाथ लगता है ... –

+0

हाहा, आप फिर से सही हैं। जब मैंने आपके उत्तर पर टिप्पणी की, तो मुझे नहीं लगता था कि यह काफी भारी हो जाएगा। मैं जगह पर गलत हूँ! लेकिन यह सवाल है कि "आप एक आवृत्ति चर को सीधे कैसे एक्सेस करते हैं," और मुझे लगता है कि जब मैं कोको विकास कर रहा हूं तो यह उपयोगी होगा, क्योंकि मैं प्रायः उन एक्सेसर्स को लिखता हूं जो एक इंस्टेंस वैरिएबल को पॉप्युलेट करते हैं यदि यह सेट नहीं है अभी तक। – AriX

+1

पहला संस्करण 4 लाइन था, लेकिन मुझे थोड़ा सा ले गया जब मैंने देखा कि यह गैर-उद्देश्य-सी प्रकारों के लिए काम नहीं करता है ... – AriX

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