Ka_rocks
Ka_rocks

Reputation:

@dynamic properties and its usage?

Can anyone give me clear picture about dynamic property and its usage? y not use the usual @property everywhere?

Upvotes: 3

Views: 1888

Answers (3)

mipadi
mipadi

Reputation: 410602

Dynamic properties are used when you don't provide an implementation at compile time, but ensure that one exists at runtime. Being a dynamic language, Objective-C can respond to messages at runtime, even if the class doesn't have an implementation at compile time.

Here's a contrived example: Let's say you have a Book class, backed by an NSMutableDictionary that contains the keys title and author. However, you want Book to respond to title and author as well, and have them as properties; title and author will grab the appropriate value from the dictionary, and setTitle: and setAuthor: will change the value stored in the dictionary. You could do so with this code:

#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;
}

Note the the methods are "created" at runtime via forwardInvocation:; hence, title and author are dynamic properties.

(This isn't the best example, but I think it gets the point across.)

Upvotes: 6

westsider
westsider

Reputation: 4985

@dynamic is (in my experience) used primarily in conjunction with Core Data and subclasses of NSManagedObject. To quote Marcus Zarra's Core Data,

By declaring them [attributes/relationships], we are telling the compiler to ignore any warnings associated with there properties because we "promise" to generate them at runtime. Naturally, if the turn up missing at runtime, then our application is going to crash.

Upvotes: 1

jer
jer

Reputation: 20236

@dynamic thing; is merely a way to inform the system not to generate getters/setters for the thing, that you (or someone else) will provide them for you—As in, they'll be there at runtime.

This is in contrast to @synthesize which tells the compiler to generate the getter/setter (as appropriate) for you.

Upvotes: 1

Related Questions