[objective-c] @synthesize vs @dynamic, what are the differences?

What are the differences between implementing a @property with @dynamic or @synthesize?

This question is related to objective-c cocoa cocoa-touch properties synthesize

The answer is


As per the documentation:

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

@dynamic tells the compiler that the accessor methods are provided at runtime.

With a little bit of investigation I found out that providing accessor methods override the @dynamic directive.

@synthesize tells the compiler to create those accessors for you (getter and setter)

@property tells the compiler that the accessors will be created, and that can be accessed with the dot notation or [object message]


One thing want to add is that if a property is declared as @dynamic it will not occupy memory (I confirmed with allocation instrument). A consequence is that you can declare property in class category.


As per the Apple documentation.

You use the @synthesize statement in a class’s implementation block to tell the compiler to create implementations that match the specification you gave in the @property declaration.

You use the @dynamic statement to tell the compiler to suppress a warning if it can’t find an implementation of accessor methods specified by an @property declaration.

More info:-

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


here is example of @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;
}

Take a look at this article; under the heading "Methods provided at runtime":

Some accessors are created dynamically at runtime, such as certain ones used in CoreData's NSManagedObject class. If you want to declare and use properties for these cases, but want to avoid warnings about methods missing at compile time, you can use the @dynamic directive instead of @synthesize.

...

Using the @dynamic directive essentially tells the compiler "don't worry about it, a method is on the way."

The @synthesize directive, on the other hand, generates the accessor methods for you at compile time (although as noted in the "Mixing Synthesized and Custom Accessors" section it is flexible and does not generate methods for you if either are implemented).


@dynamic is typically used (as has been said above) when a property is being dynamically created at runtime. NSManagedObject does this (why all its properties are dynamic) -- which suppresses some compiler warnings.

For a good overview on how to create properties dynamically (without NSManagedObject and CoreData:, see: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#//apple_ref/doc/uid/TP40008048-CH102-SW1


As others have said, in general you use @synthesize to have the compiler generate the getters and/ or settings for you, and @dynamic if you are going to write them yourself.

There is another subtlety not yet mentioned: @synthesize will let you provide an implementation yourself, of either a getter or a setter. This is useful if you only want to implement the getter for some extra logic, but let the compiler generate the setter (which, for objects, is usually a bit more complex to write yourself).

However, if you do write an implementation for a @synthesize'd accessor it must still be backed by a real field (e.g., if you write -(int) getFoo(); you must have an int foo; field). If the value is being produce by something else (e.g. calculated from other fields) then you have to use @dynamic.


Examples related to objective-c

Adding a UISegmentedControl to UITableView Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Warp \ bend effect on a UIView? Use NSInteger as array index Detect if the device is iPhone X Linker Command failed with exit code 1 (use -v to see invocation), Xcode 8, Swift 3 ITSAppUsesNonExemptEncryption export compliance while internal testing? How to enable back/left swipe gesture in UINavigationController after setting leftBarButtonItem? Change status bar text color to light in iOS 9 with Objective-C

Examples related to cocoa

How to update a single pod without touching other dependencies How to initialise a string from NSData in Swift Input from the keyboard in command line application Get current NSDate in timestamp format Xcode build failure "Undefined symbols for architecture x86_64" Cocoa Autolayout: content hugging vs content compression resistance priority setValue:forUndefinedKey: this class is not key value coding-compliant for the key iOS - Build fails with CocoaPods cannot find header files Get Current date & time with [NSDate date] Remove all whitespaces from NSString

Examples related to cocoa-touch

Include of non-modular header inside framework module Move textfield when keyboard appears swift Create space at the beginning of a UITextField Navigation bar with UIImage for title Generate a UUID on iOS from Swift How do I write a custom init for a UIView subclass in Swift? creating custom tableview cells in swift How would I create a UIAlertView in Swift? Get current NSDate in timestamp format How do you add an in-app purchase to an iOS application?

Examples related to properties

Property 'value' does not exist on type 'EventTarget' How to read data from java properties file using Spring Boot Kotlin - Property initialization using "by lazy" vs. "lateinit" react-router - pass props to handler component Specifying trust store information in spring boot application.properties Can I update a component's props in React.js? Property getters and setters Error in Swift class: Property not initialized at super.init call java.util.MissingResourceException: Can't find bundle for base name 'property_file name', locale en_US How to use BeanUtils.copyProperties?

Examples related to synthesize

@synthesize vs @dynamic, what are the differences?