Domanda

Quali sono le differenze tra l'implementazione di un @property con @dynamic o @synthesize?

È stato utile?

Soluzione

@synthesize genererà metodi getter e setter per la vostra proprietà. @dynamic solo dice al compilatore che i metodi getter e setter sono implementati non dalla classe stessa, ma da qualche altra parte (come la superclasse o saranno forniti in fase di esecuzione).

Utilizza per @dynamic sono per esempio con sottoclassi di NSManagedObject (CoreData) oppure quando si desidera creare uno sbocco per una proprietà definita da una superclasse che non è stato definito come una presa di corrente.

@dynamic inoltre può essere utilizzato per delegare la responsabilità di attuare le funzioni di accesso. Se si sceglie di implementare le funzioni di accesso da soli all'interno della classe, che normalmente non utilizzati @dynamic.

Classe Super:

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

Sottoclasse:

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

Altri suggerimenti

Date un'occhiata a questo articolo ; sotto il titolo "Metodi forniti in fase di esecuzione":

  

Alcune funzioni di accesso vengono creati in modo dinamico in fase di esecuzione, come ad esempio alcune quelli usati in classe NSManagedObject di CoreData. Se si vuole dichiarare e utilizzare le proprietà per questi casi, ma si vuole evitare gli avvertimenti circa i metodi mancanti al momento della compilazione, è possibile utilizzare la direttiva @dynamic invece di @synthesize.

     

...

     

Uso della direttiva @dynamic dice in sostanza il compilatore "non ti preoccupare, un metodo è in cammino".

La direttiva @synthesize, d'altra parte, genera i metodi di accesso per voi in fase di compilazione (anche se, come indicato nelle "funzioni d'accesso personalizzate miscelazione sintetizzato e" sezione è flessibile e non genera metodi per voi se uno dei due sono implementati) .

Come altri hanno detto, in generale, si utilizza @synthesize di avere il compilatore genera i getter e / o le impostazioni per voi, e @dynamic se avete intenzione di scrivere voi stessi.

C'è un altro sottigliezza non è ancora citato: @synthesize consente di fornire un'implementazione te stesso, sia di un getter o setter. Questo è utile se si desidera solo implementare il getter per un po 'di logica in più, ma lasciare che il compilatore genera il setter (che, per gli oggetti, è di solito un po' più complesso per scrivere).

Tuttavia, se si fa scrivere un'implementazione per un @ synthesize'd accessor deve ancora essere sostenuta da un campo vero e proprio (ad esempio, se si scrive -(int) getFoo(); è necessario disporre di un campo int foo;). Se il valore è essere prodotti da qualcos'altro (ad esempio calcolato da altri campi), allora è necessario utilizzare @dynamic.

@dynamic è tipicamente usato (come detto sopra) quando una proprietà viene creato dinamicamente in fase di esecuzione. NSManagedObject fa questo (perché tutte le sue proprietà sono dinamici) -. Che sopprime alcuni avvisi del compilatore

Per una buona panoramica su come creare le proprietà in modo dinamico (senza NSManagedObject e CoreData :, vedere: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html# // apple_ref / doc / uid / TP40008048-CH102-SW1

ecco esempio di @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:"v@:@"];
    } 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;
}

Come per la documentazione:

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

@dynamic dice al compilatore che i metodi accessori sono forniti in fase di esecuzione.

Con un po 'di indagine ho scoperto che forniscono metodi accessori ignorare l'istruzione @dynamic.

@synthesize dice al compilatore di creare quelle di accesso per voi (getter e setter)

@property dice al compilatore che saranno create le funzioni di accesso, e che si può accedere con la notazione punto o [messaggio oggetto]

Una cosa voglio aggiungere è che se una proprietà è dichiarato come @dynamic non occuperà memoria (ho confermato con lo strumento di allocazione). Una conseguenza è che è possibile dichiarare proprietà nella categoria di classe.

Come per la documentazione di Apple.

Si utilizza l'istruzione @synthesize nel blocco implementazione di una classe per dire al compilatore di creare implementazioni che corrispondono alla specifica avete dato nella dichiarazione @property.

Si utilizza l'istruzione @dynamic per dire al compilatore di sopprimere un avviso se non riesce a trovare un'implementazione di metodi di accesso specificati da una dichiarazione @property.

Più informazioni: -

https://developer.apple. com / library / ios / documentazione / General / concettuale / DevPedia-CocoaCore / DeclaredProperty.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top