답변:
@synthesize는 속성에 대한 getter 및 setter 메소드를 생성합니다. @dynamic은 단지 getter와 setter 메소드가 클래스 자체가 아닌 다른 곳 (수퍼 클래스와 같거나 런타임에 제공됨)에 의해 구현된다는 것을 컴파일러에게 알려줍니다.
@dynamic의 사용은 예를 들어 NSManagedObject
(CoreData)의 서브 클래스 를 사용하거나 콘센트로 정의되지 않은 수퍼 클래스에 의해 정의 된 속성에 대한 콘센트를 작성하려는 경우입니다.
@dynamic을 사용하여 접근자를 구현하는 책임을 위임 할 수도 있습니다. 클래스 내에서 접근자를 직접 구현하면 일반적으로 @dynamic을 사용하지 않습니다.
슈퍼 클래스 :
@property (nonatomic, retain) NSButton *someButton;
...
@synthesize someButton;
아강:
@property (nonatomic, retain) IBOutlet NSButton *someButton;
...
@dynamic someButton;
NSUnknownKeyException
제거 할 때 동적 속성에 오류 가 발생했습니다 @synthesize
(Xcode 3.2에서 @property와 일치하는 ivar가없는 오류 b / c가 발생했습니다). 추가 @dynamic
문제 해결-지금 컴파일하고 잘 실행하십시오. 감사!
@property
되지 않은 품목도 @synthesize
없습니다 @dynamic
. 각 속성에 대해 _propertyName
적절한 getter 및 setter와 함께 밑줄이있는 ivar 이 만들어집니다.
한 번 봐 가지고 이 글을 ; "런타임에 제공되는 방법"제목 아래 :
CoreData의 NSManagedObject 클래스에서 사용되는 특정 접근 자와 같은 일부 접근자는 런타임에 동적으로 생성됩니다. 이러한 경우에 속성을 선언하고 사용하려고하지만 컴파일시 누락 된 메서드에 대한 경고를 피하려면 @synthesize 대신 @dynamic 지시문을 사용할 수 있습니다.
...
@dynamic 지시문을 사용하면 본질적으로 컴파일러에게 "걱정하지 말고 방법이 진행 중"이라고 지시합니다.
@synthesize
(이하 "혼합 합성하여 사용자 접근 자"절에서 언급 한 바와 같이이 유연하고 중 하나를하는 것은 구현하는 경우 당신을위한 방법을 생성하지 않지만) 지침은, 다른 한편으로는, 컴파일시에 당신을위한 접근 방법을 생성합니다.
다른 사람들이 말했듯이 일반적으로 @synthesize를 사용하여 컴파일러가 getter 및 / 또는 설정을 생성하게하고 @dynamic을 사용하여 직접 작성하십시오.
아직 언급되지 않은 또 다른 미묘한 점이 있습니다. @synthesize 를 사용하면 getter 또는 setter의 구현을 직접 제공 할 수 있습니다. 이것은 약간의 추가 로직을 위해 getter를 구현하고 싶지만 컴파일러가 setter를 생성하게하는 경우에 유용합니다.
그러나 @ synthesize'd 접근 자에 대한 구현을 작성하는 경우 여전히 실제 필드에 의해 백업되어야합니다 (예를 들어 작성 -(int) getFoo();
하는 경우 int foo;
필드 가 있어야 함 ). 다른 필드에서 계산 된 다른 값으로 값을 생성하는 경우 @dynamic을 사용해야합니다.
@dynamic
자신이 직접 작성하려는 경우"아니요, 직접 작성하면 동적을 사용하지 않습니다. @dynamic
컴파일러 검사를 해제하여 구현했는지 확인하십시오. 직접 구현 한 경우 컴파일러에서 확인하기를 원합니다.
@dynamic은 속성이 런타임에 동적으로 생성 될 때 일반적으로 사용됩니다 (위에서 언급했듯이). NSManagedObject가이를 수행합니다 (모든 속성이 동적 인 이유). 일부 컴파일러 경고가 표시되지 않습니다.
NSManagedObject 및 CoreData없이 속성을 동적으로 생성하는 방법에 대한 개요는 http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#//을 참조하십시오. apple_ref / doc / uid / TP40008048-CH102-SW1
다음은 @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;
}
설명서에 따라 :
@dynamic은 접근 자 메서드가 런타임에 제공된다는 것을 컴파일러에 알려줍니다.
약간의 조사를 통해 접근 자 메소드를 제공하는 것이 @dynamic 지시문을 재정의한다는 것을 알았습니다.
@synthesize는 컴파일러에게 접근자를 생성하도록 지시합니다 (getter and setter)
@property는 컴파일러에게 접근자가 생성되고 점 표기법 또는 [개체 메시지]로 액세스 할 수 있음을 알려줍니다.
추가 할 한 가지 속성은 속성이 @dynamic으로 선언되면 메모리를 차지하지 않는다는 것입니다 (할당 장치로 확인했습니다). 결과적으로 클래스 범주에서 속성을 선언 할 수 있습니다.
Apple 설명서에 따라.
@synthesize
클래스의 구현 블록에서 명령문을 사용하여 컴파일러가 사용자가 지정한 사양과 일치하는 구현을 작성하도록 지시합니다.@property
.
이 @dynamic
명령문을 사용하여 @property
선언에 지정된 접근 자 메소드의 구현을 찾을 수없는 경우 경고를 억제하도록 컴파일러에 지시합니다 .
더 많은 정보:-