2009-07-21 18 views

उत्तर

708

@ सिंथेसाइज आपकी संपत्ति के लिए गेटर और सेटटर विधियां उत्पन्न करेगा। @ गतिशील बस संकलक को बताता है कि गेटटर और सेटर विधियों को कक्षा द्वारा ही लागू नहीं किया जाता है, लेकिन कहीं और (जैसे सुपरक्लास या रनटाइम पर प्रदान किया जाएगा)।

@ गतिशील के लिए उपयोग करता है उदा। NSManagedObject (कोरडाटा) के उप-वर्गों के साथ या जब आप एक सुपरक्लास द्वारा परिभाषित संपत्ति के लिए आउटलेट बनाना चाहते हैं जिसे आउटलेट के रूप में परिभाषित नहीं किया गया था।

@ गतिशील भी एक्सेसर्स को लागू करने की ज़िम्मेदारी का प्रतिनिधित्व करने के लिए उपयोग किया जा सकता है। यदि आप क्लास के भीतर एक्सेसर्स को स्वयं लागू करते हैं तो आप आमतौर पर @dynamic का उपयोग नहीं करते हैं।

सुपर वर्ग:

@property (nonatomic, retain) NSButton *someButton; 
... 
@synthesize someButton; 

उपवर्ग:

@property (nonatomic, retain) IBOutlet NSButton *someButton; 
... 
@dynamic someButton; 
+23

100% सही नहीं; गतिशील डिफ़ॉल्ट है यदि आप या तो @ सिंथेसाइज़ या @ गतिशील सेट नहीं करते हैं। @ गतिशील निर्दिष्ट करने का मतलब केवल यह है कि आप संपत्ति घोषणा के हस्ताक्षर के आधार पर संपत्ति एक्सेसर्स को सही ढंग से कार्यान्वित करने की ज़िम्मेदारी लेते हैं। – Kevlar

+67

वास्तव में, @ गतिशील साधनों को लागू करने की ज़िम्मेदारी का मतलब नहीं है। यदि आप क्लास के भीतर एक्सेसर्स को स्वयं लागू करते हैं तो आप आमतौर पर @dynamic का उपयोग नहीं करते हैं। – diederikh

+2

मुझे अपनी गतिशील संपत्ति के साथ 'NSUnknownKEEceptionception' त्रुटियां मिल रही थीं जब मैंने '@ संश्लेषण' रेखा को हटा दिया था (एक्सकोड 3.2 मुझे एक त्रुटि बी/सी दे रहा था, मेरे पास मेरे @property के लिए कोई मिलान नहीं था)। 'गतिशील' जोड़ना समस्या को हल करता है - संकलित करता है और अभी ठीक चलाता है। धन्यवाद! – pix0r

206

this article पर एक नज़र डालें; शीर्षलेख के तहत "रनटाइम पर दिए गए तरीके":

कुछ एक्सेसर्स रनटाइम पर गतिशील रूप से बनाए जाते हैं, जैसे कुछ कोरडाटा के एनएसएमएनेज्ड ऑब्जेक्ट क्लास में उपयोग किए जाते हैं। यदि आप इन मामलों के लिए संपत्ति घोषित करना और उपयोग करना चाहते हैं, लेकिन संकलन समय पर अनुपलब्ध विधियों के बारे में चेतावनियों से बचना चाहते हैं, तो आप @ सिंथेसाइज़ के बजाय @ डायनामिक निर्देश का उपयोग कर सकते हैं।

...

का उपयोग @dynamic निर्देश अनिवार्य रूप से संकलक कहता है "इसके बारे में चिंता मत करो, एक विधि रास्ते पर है।"

@synthesize निर्देश, दूसरे हाथ पर, संकलन समय पर आप के लिए एक्सेसर तरीकों हालांकि अनुभाग में "संश्लेषित और मिश्रण कस्टम पहुंचकर्ता" में बताया गया है उत्पन्न करता है (यह लचीला है और या तो अगर आप के लिए तरीकों उत्पन्न नहीं करता है लागू कर रहे हैं)।

+25

यह morer-correcter आदमी है। यह उत्तर एकमात्र उत्तर है जो रनटाइम पर बनाए गए तरीकों के बारे में बात करता है, जो वास्तव में शीर्ष वोट वाले उत्तर एटीएम – bobobobo

+1

से अधिक भावना को पकड़ने लगता है, हर किसी को इसे ऊपर उठाना चाहिए। –

+0

@ अंकित श्रीवास्तव "गतिशील" भी इवर बनाते हैं? – onmyway133

29

के रूप में अन्य लोगों ने कहा, सामान्य रूप में आप @synthesize का उपयोग संकलक के लिए आप के लिए ही टिककर खेल और/या सेटिंग उत्पन्न, और @ गतिशील अगर आप उन्हें खुद लिखने जा रहे हैं।

एक और सूक्ष्मता अभी तक का उल्लेख नहीं किया है: @synthesize आप एक कार्यान्वयन खुद प्रदान करते हैं या तो एक गेटर या एक सेटर की अनुमति देता है। यह उपयोगी है अगर आप केवल कुछ अतिरिक्त तर्क के लिए गेटर को कार्यान्वित करना चाहते हैं, लेकिन संकलक को सेटटर उत्पन्न करने दें (जो, ऑब्जेक्ट्स के लिए आमतौर पर लिखने के लिए थोड़ा अधिक जटिल होता है)।

हालांकि, अगर आप एक @ के लिए एक कार्यान्वयन लिखने synthesize'd accessor यह अभी भी एक वास्तविक क्षेत्र द्वारा समर्थित किया जाना चाहिए करते हैं (जैसे, यदि आप -(int) getFoo(); बारे में आप एक int foo; क्षेत्र होनी चाहिए)। यदि मूल्य किसी अन्य चीज़ द्वारा उत्पादित किया जा रहा है (उदा। अन्य क्षेत्रों से गणना की जाती है) तो आपको @ गतिशील का उपयोग करना होगा।

+2

+1: @ गतिशील आपको अपने वर्ग इंटरफ़ेस में और आत्मनिरीक्षण के माध्यम से परिभाषित वैरिएबल के लिए एक्सेसर्स बनाने देता है। – mahboudz

+24

"और '@ गतिशील' यदि आप उन्हें स्वयं लिखने जा रहे हैं" नहीं, यदि आप उन्हें स्वयं लिखते हैं तो आप गतिशीलता का उपयोग नहीं करते हैं। 'गतिशील 'यह सुनिश्चित करने के लिए कि आपने उन्हें लागू किया है, कंपाइलर जांच बंद कर देता है। यदि आपने उन्हें स्वयं लागू किया है, तो आप संकलक को जांचना चाहते हैं। – user102008

14

@ गतिशील आमतौर पर उपयोग किया जाता है (ऊपर बताया गया है) जब संपत्ति को रनटाइम पर गतिशील रूप से बनाया जा रहा है। NSManagedObject यह करता है (क्यों इसकी सभी गुण गतिशील हैं) - जो कुछ कंपाइलर चेतावनियों को दबाता है।

कैसे NSManagedObject बिना गतिशील रूप से गुण पैदा करने के लिए (और CoreData :, देखने पर एक अच्छा अवलोकन के लिए: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#//apple_ref/doc/uid/TP40008048-CH102-SW1

6

एक बात जोड़ना चाहते है कि एक संपत्ति के रूप में @dynamic यह स्मृति पर कब्जा नहीं होंगे घोषित किया जाता है, तो (मैं । आवंटन साधन के साथ पुष्टि की) एक परिणाम यह है कि आप वर्ग श्रेणी में संपत्ति की घोषणा कर सकता है

+0

यदि मैं एक श्रेणी में एक संपत्ति सेटर को ओवरराइड करता हूं और इसे गतिशील बनाता हूं, तो क्या यह गारंटी होगी कि ओवरराइड रनटाइम पर उपयोग किया जाएगा, न कि माता-पिता वर्ग के सेटर? ऐप्पल दस्तावेज़ों से: "यदि किसी वर्ग में घोषित विधि का नाम मूल वर्ग में एक विधि जैसा ही है ... व्यवहार को परिभाषित किया गया है कि रनटाइम पर किस विधि कार्यान्वयन का उपयोग किया जाता है।" –

+0

नहीं, मुझे लगता है कि व्यवहार अभी भी अनिर्धारित है। श्रेणी गतिशील में संपत्ति बनाना संपत्ति सेटटर विधि की रनटाइम प्राथमिकता को नहीं बदलता है। –

13

here is @dynamic

#import <Foundation/Foundation.h> 

@interface Book : NSObject 
{ 
    NSMutableDictionary *data; 
} 
@property (retain) NSString *title; 
@property (retain) NSString *author; 
@end 

@implementation Book 
@dynamic title, author; 

- (id)init 
{ 
    if ((self = [super init])) { 
     data = [[NSMutableDictionary alloc] init]; 
     [data setObject:@"Tom Sawyer" forKey:@"title"]; 
     [data setObject:@"Mark Twain" forKey:@"author"]; 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    [data release]; 
    [super dealloc]; 
} 

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector 
{ 
    NSString *sel = NSStringFromSelector(selector); 
    if ([sel rangeOfString:@"set"].location == 0) { 
     return [NSMethodSignature signatureWithObjCTypes:"[email protected]:@"]; 
    } else { 
     return [NSMethodSignature signatureWithObjCTypes:"@@:"]; 
    } 
} 

- (void)forwardInvocation:(NSInvocation *)invocation 
{ 
    NSString *key = NSStringFromSelector([invocation selector]); 
    if ([key rangeOfString:@"set"].location == 0) { 
     key = [[key substringWithRange:NSMakeRange(3, [key length]-4)] lowercaseString]; 
     NSString *obj; 
     [invocation getArgument:&obj atIndex:2]; 
     [data setObject:obj forKey:key]; 
    } else { 
     NSString *obj = [data objectForKey:key]; 
     [invocation setReturnValue:&obj]; 
    } 
} 

@end 

int main(int argc, char **argv) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    Book *book = [[Book alloc] init]; 
    printf("%s is written by %s\n", [book.title UTF8String], [book.author UTF8String]); 
    book.title = @"1984"; 
    book.author = @"George Orwell"; 
    printf("%s is written by %s\n", [book.title UTF8String], [book.author UTF8String]); 

    [book release]; 
    [pool release]; 
    return 0; 
} 
9

प्रलेखन के अनुसार के उदाहरण:।

https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html

@dynamic संकलक कि एक्सेसर तरीकों कार्यावधि में प्रदान की जाती हैं बताता है।

थोड़ी सी जांच के साथ मुझे पता चला कि एक्सेसर विधियों को @ डायनामिक निर्देश ओवरराइड प्रदान करना है।

@synthesize आप के लिए उन accessors बनाने के लिए संकलक (गेटर और सेटर)

@property संकलक accessors बनाया जाएगा कि बताता है बताता है, और है कि डॉट नोटेशन या [वस्तु संदेश] के साथ पहुँचा जा सकता है

0

ऐप्पल दस्तावेज के अनुसार।

आप एक वर्ग के कार्यान्वयन ब्लॉक में @synthesize कथन का उपयोग कार्यान्वयन कि विनिर्देश आप @property घोषणा में दे दी है से मेल बनाने के लिए संकलक बताने के लिए।

आप @dynamic कथन का उपयोग करते हैं ताकि संकलक को दबाने के लिए संकलक को बताने के लिए कहा जा सके कि अगर @property घोषणा द्वारा निर्दिष्ट एक्सेसर विधियों के कार्यान्वयन को नहीं मिला है।

और जानकारी: -

https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/DeclaredProperty.html

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