Jawaban:
@synthesize akan menghasilkan metode pengambil dan penyetel untuk properti Anda. @dynamic hanya memberitahu kompiler bahwa metode pengambil dan penyetel diimplementasikan bukan oleh kelas itu sendiri tetapi di tempat lain (seperti superclass atau akan disediakan saat runtime).
Penggunaan untuk @dynamic misalnya dengan subkelas NSManagedObject
(CoreData) atau ketika Anda ingin membuat outlet untuk properti yang ditentukan oleh superclass yang tidak didefinisikan sebagai outlet.
@dynamic juga dapat digunakan untuk mendelegasikan tanggung jawab mengimplementasikan accessors. Jika Anda menerapkan accessors sendiri di dalam kelas maka Anda biasanya tidak menggunakan @dynamic.
Kelas super:
@property (nonatomic, retain) NSButton *someButton;
...
@synthesize someButton;
Subkelas:
@property (nonatomic, retain) IBOutlet NSButton *someButton;
...
@dynamic someButton;
NSUnknownKeyException
kesalahan dengan properti dinamis saya ketika saya menghapus @synthesize
baris (Xcode 3.2 memberi saya kesalahan b / c saya tidak punya ivar yang cocok untuk @property saya). Menambahkan @dynamic
memperbaiki masalah - kompilasi dan berjalan dengan baik sekarang. Terima kasih!
@property
item yang tidak memiliki @synthesize
atau @dynamic
akan disintesis secara otomatis. Untuk setiap properti, sebuah ivar dengan garis bawah utama, misalnya _propertyName
akan dibuat, bersama dengan pengambil dan penyetel yang sesuai.
Lihatlah artikel ini ; di bawah judul "Metode yang disediakan saat runtime":
Beberapa accessor dibuat secara dinamis saat runtime, seperti yang digunakan di kelas NSManagedObject CoreData. Jika Anda ingin mendeklarasikan dan menggunakan properti untuk kasus-kasus ini, tetapi ingin menghindari peringatan tentang metode yang hilang pada waktu kompilasi, Anda dapat menggunakan direktif @dynamic alih-alih @sintesis.
...
Menggunakan direktif @dynamic pada dasarnya memberitahu kompiler "jangan khawatir tentang hal itu, metode sedang dalam perjalanan."
The @synthesize
direktif, di sisi lain, menghasilkan metode accessor untuk Anda pada waktu kompilasi (meskipun seperti yang tercantum dalam bagian "Pencampuran disintesis dan Custom Accessors" itu adalah fleksibel dan tidak menghasilkan metode untuk Anda jika salah diimplementasikan).
Seperti yang orang lain katakan, secara umum Anda menggunakan @synthesize untuk membuat kompiler menghasilkan getter dan / atau pengaturan untuk Anda, dan @dynamic jika Anda ingin menulisnya sendiri.
Ada kehalusan lain yang belum disebutkan: @synthesize akan membiarkan Anda memberikan implementasi sendiri, baik dari pengambil atau penyetel. Ini berguna jika Anda hanya ingin mengimplementasikan pengambil untuk beberapa logika tambahan, tetapi biarkan kompiler menghasilkan setter (yang, untuk objek, biasanya sedikit lebih rumit untuk menulis sendiri).
Namun, jika Anda menulis implementasi untuk pengakses @ synthesize'd itu masih harus didukung oleh bidang nyata (misalnya, jika Anda menulis -(int) getFoo();
Anda harus memiliki int foo;
bidang). Jika nilai sedang diproduksi oleh sesuatu yang lain (misalnya dihitung dari bidang lain) maka Anda harus menggunakan @dynamic.
@dynamic
jika Anda akan menulisnya sendiri" Tidak, Anda TIDAK menggunakan dinamis jika Anda menulisnya sendiri. @dynamic
mematikan pemeriksaan kompiler untuk memastikan Anda menerapkannya. Jika Anda menerapkannya sendiri, Anda ingin kompilator memeriksa.
@dynamic biasanya digunakan (seperti yang telah dikatakan di atas) ketika sebuah properti sedang dibuat secara dinamis saat runtime. NSManagedObject melakukan ini (mengapa semua propertinya dinamis) - yang menekan beberapa peringatan kompiler.
Untuk gambaran umum yang baik tentang cara membuat properti secara dinamis (tanpa NSManagedObject dan CoreData :, lihat: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#//// apple_ref / doc / uid / TP40008048-CH102-SW1
di sini adalah contoh @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;
}
Sesuai dokumentasi:
@dynamic memberi tahu kompiler bahwa metode accessor disediakan saat runtime.
Dengan sedikit penyelidikan saya menemukan bahwa menyediakan metode accessor mengesampingkan direktif @dynamic.
@synthesize memberitahu kompiler untuk membuat pengakses tersebut untuk Anda (pengambil dan penyetel)
@ properti memberitahu kompiler bahwa accessors akan dibuat, dan yang dapat diakses dengan notasi titik atau [pesan objek]
Satu hal yang ingin ditambahkan adalah bahwa jika properti dideklarasikan sebagai @dynamic tidak akan menempati memori (saya dikonfirmasi dengan instrumen alokasi). Konsekuensinya adalah Anda dapat mendeklarasikan properti dalam kategori kelas.
Sesuai dokumentasi Apple.
Anda menggunakan @synthesize
pernyataan di blok implementasi kelas untuk memberi tahu kompiler untuk membuat implementasi yang cocok dengan spesifikasi yang Anda berikan dalam @property
deklarasi.
Anda menggunakan @dynamic
pernyataan untuk memberi tahu kompiler untuk menekan peringatan jika tidak dapat menemukan implementasi metode accessor yang ditentukan oleh @property
deklarasi.
Info lebih lanjut:-