[objective-c] @synthesize와 @dynamic의 차이점은 무엇입니까?

을 구현 사이의 차이점은 무엇입니까 @property@dynamic또는 @synthesize?



답변

@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;


답변

한 번 봐 가지고 이 글을 ; “런타임에 제공되는 방법”제목 아래 :

CoreData의 NSManagedObject 클래스에서 사용되는 특정 접근 자와 같은 일부 접근자는 런타임에 동적으로 생성됩니다. 이러한 경우에 속성을 선언하고 사용하려고하지만 컴파일시 누락 된 메서드에 대한 경고를 피하려면 @synthesize 대신 @dynamic 지시문을 사용할 수 있습니다.

@dynamic 지시문을 사용하면 본질적으로 컴파일러에게 “걱정하지 말고 방법이 진행 중”이라고 지시합니다.

@synthesize(이하 “혼합 합성하여 사용자 접근 자”절에서 언급 한 바와 같이이 유연하고 중 하나를하는 것은 구현하는 경우 당신을위한 방법을 생성하지 않지만) 지침은, 다른 한편으로는, 컴파일시에 당신을위한 접근 방법을 생성합니다.


답변

다른 사람들이 말했듯이 일반적으로 @synthesize를 사용하여 컴파일러가 getter 및 / 또는 설정을 생성하게하고 @dynamic을 사용하여 직접 작성하십시오.

아직 언급되지 않은 또 다른 미묘한 점이 있습니다. @synthesize 를 사용하면 getter 또는 setter의 구현을 직접 제공 수 있습니다. 이것은 약간의 추가 로직을 위해 getter를 구현하고 싶지만 컴파일러가 setter를 생성하게하는 경우에 유용합니다.

그러나 @ synthesize’d 접근 자에 대한 구현을 작성하는 경우 여전히 실제 필드에 의해 백업되어야합니다 (예를 들어 작성 -(int) getFoo();하는 경우 int foo;필드 가 있어야 함 ). 다른 필드에서 계산 된 다른 값으로 값을 생성하는 경우 @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;
}


답변

설명서에 따라 :

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

@dynamic은 접근 자 메서드가 런타임에 제공된다는 것을 컴파일러에 알려줍니다.

약간의 조사를 통해 접근 자 메소드를 제공하는 것이 @dynamic 지시문을 재정의한다는 것을 알았습니다.

@synthesize는 컴파일러에게 접근자를 생성하도록 지시합니다 (getter and setter)

@property는 컴파일러에게 접근자가 생성되고 점 표기법 또는 [개체 메시지]로 액세스 할 수 있음을 알려줍니다.


답변

추가 할 한 가지 속성은 속성이 @dynamic으로 선언되면 메모리를 차지하지 않는다는 것입니다 (할당 장치로 확인했습니다). 결과적으로 클래스 범주에서 속성을 선언 할 수 있습니다.