The @dynamic in Objective-c

Source: Internet
Author: User

first, the difference between the @dynamic and the @synthesize @property has two corresponding words, one is@synthesize, one is @dynamic. If @synthesize and @dynamic are not written, then the default is @syntheszie var =_var; The semantics of @synthesize is that if you do not implement setter methods and getter methods manually, the compiler will automatically add these two methods to you. @dynamic tells the compiler that the setter and getter methods of the property are implemented by the user themselves and are not generated automatically. (Of course, for ReadOnly properties, only getter is required). If a property is declared as @dynamic var, then you do not provide the @setter method and the @getter method, the compile time is not a problem, but when the program runs to Instance.var=somevar, because the lack of setter method can cause the program to crash, or when run to Somevar =Var, the lack of getter methods can also cause crashes. Compile-time is no problem, the runtime executes the corresponding method, which is called dynamic binding. Second, through the private variables to achieve @dynamic access method1) Book.h#import<Foundation/Foundation.h>#import<CoreData/CoreData.h>@interfacebook:nsobject{@private__strong NSString*_name; __strong NSString*_author;} @property (nonatomic, copy) NSString*Name: @property (nonatomic, copy) NSString*author; @property (nonatomic, copy) NSString*version;@end2) BOOK.M#import "Book.h" @implementationbook@dynamic name; @dynamic author;@synthesizeVersion =_version;- (ID) init{ Self=[Super Init]; if(self) {}returnSelf ;}-(NSString *) name{if(Nil = =_name) {_name=@"You forgot Inputbook name"; }    return_name;}- (void) SetName: (NSString *) name{_name=name; NSLog (@"_name address:%p", _name);}-(NSString *) author{if(Nil = =_author) {_author=@"You forgot Inputbook author"; }    return_author;}- (void) Setauthor: (NSString *) author{_author=author;}@endAs you can see from the code above, with @dynamic, you can access a private variable in the access method to assign a value or to take a value. and @synthesize directly with the@synthesizevar =_var: To make attributes and private variables directly equal. This is the difference between the two in the writing form. Third, through message forwarding to achieve @dynamic access method if the @dynamic var is used for a property=_var, the compiler immediately errors. You won't be able to use _var like @synthesize in the setter method and getter method of Var, but you can't write the setter method and getter method as follows.- (void) SetVar: (ID) newvar{Self.var=Newvar;}- (void) var{returnSelf.var;} Both of these methods call themselves, causing an infinite loop that directly causes the program to crash. A setter and getter method using message forwarding mechanism to implement @dynamic is provided here. First on the code:1) Book.h#import<Foundation/Foundation.h>@interfacebook:nsobject{@privatensmutabledictionary*_propertiesdict;} @property (nonatomic, copy) NSString*Name: @property (nonatomic, copy) NSString*author; @property (nonatomic, copy) NSString*version;@end2) BOOK.M#import "Book.h"@implementationbook@dynamic name;//cannot be written as name = _name, otherwise the compiler will immediately error@dynamic author;@synthesizeversion;- (ID) init{ Self=[Super Init]; if(self) {_propertiesdict=[[Nsmutabledictionary alloc] init]; }    returnSelf ;} -(Nsmethodsignature *) Methodsignatureforselector: (SEL) selector{nsstring*sel =Nsstringfromselector (selector); if(Sel rangeofstring:@"Set"].location = =0)    {        return[Nsmethodsignature signaturewithobjctypes:"[Email protected]:@"]; }    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];    [_propertiesdict setobject:obj Forkey:key]; }    Else{nsstring*obj =[_propertiesdict Objectforkey:key]; [Invocation Setreturnvalue:&obj]; }} @end 3) main.m#import<Foundation/Foundation.h>#import "Book.h" intMainintargcConst Char*argv[]) {@autoreleasepool { book*book =[[Book alloc] init]; Book.name=@"C + + primer"; Book.author=@"Stanley B.lippman"; Book.version=@"5.0"; NSLog (@"%@", Book.name); NSLog (@"%@", Book.author); NSLog (@"%@", book.version); }    return 0;} Program Analysis:1before adding the message forwarding function to a program, you must overwrite two methods, namely Methodsignatureforselector: and Forwardinvocation:. Methodsignatureforselector: The effect of creating a valid method signature for a message implemented by another class. Forwardinvocation: Forwards the selector to an object that actually implements the message. 2) objective-the methods in C are hidden two parameters by default: Self and _cmd. Self points to the object itself, and _cmd points to the method itself. Give two examples to illustrate: example one:-(NSString *name This method actually has two parameters: Self and _cmd. Example two:- (void) SetValue: (intVal This method actually has three parameters: Self, _cmd, and Val. The parameter type of a method that is specified as a dynamic implementation is as follows: A. The first parameter type must be an ID (that is, the type of self) B. The second parameter type must be the SEL (that is, the _cmd type) C. From the third parameter, you can define it as the parameter type of the original method.    Take two examples to illustrate: example one: setheight: (cgfloat) The parameter height in height is floating-point, so the third parameter type is F. Example two: Again such as SetName: (NSString*the parameter name in name is of type string, so the third parameter type is @3There is a code in MAIN.M that is Book.name =@"C + + primer"When the program runs here, it will go to BOOK.M for SetName: This assignment method. However, BOOK.M does not have this method, so the program enters the Methodsignatureforselector: in the message forwarding. After the execution is completed, the"[Email protected]:@"returned as a method signature type. Here [email protected]:@ what is it?    In fact, the first character v here means that the return type of the function is void, followed by the explanation in the three character reference above 2) to know, respectively, is self, _cmd, name, the type ID of the three parameter, SEL, NSString. Then the program enters the Forwardinvocation method. Get the key for the method name SetName: And then use [invocationgetargument:&objatindex:2]; Get to the parameter value, here is "C + +Primer ". Why is the index here to take 2?    As previously analyzed, the No. 0 parameter is self, the 1th parameter is _cmd, and the 2nd parameter is the one with the back of the method. Finally, a variable dictionary is used to assign values. This completes the entire setter process. 4There is a code in MAIN.M that is NSLog (@"%@", book.name); When the program runs here, it will go to BOOK.M to find the name of the value method. However, BOOK.M does not have this method of value, so the program into the Methodsignatureforselector: in the message forwarding. After the execution is completed, the"@@:"returned as a method signature type.    Here the first character @ represents the function return type NSString, the second character @ represents the type ID of self, and the third character: the type SEL that represents _cmd. Then the program enters the Forwardinvocation method. The resulting key is the method name. Finally, the corresponding value is obtained from the dictionary according to this key, so the whole getter process is completed. 5Note that the process of debugging the code, we find only the assignment and value of name and author into Methodsignatureforselector: and Forwardinvocation: both methods. There is also an assignment and value for the property version, and does not enter Methodsignatureforselector: and forwardinvocation: These two methods. This is because the Version property is identified as@synthesize, the compiler automatically adds setversion and version two methods, so no message forwarding is necessary. Iv. @dynamic use in Nsmanagedobject subclasses @dynamic the most common use is in Nsmanagedobject, where programming setters and getter methods are not required. The reason: @dynamic tell the compiler not to do the processing, so that the compilation through, its getter and setter method will be dynamically created at run time, by the core data framework for such properties to generate access methods. 

The @dynamic in Objective-c

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.