iOS Dynamics: How to add properties dynamically--association (e.g. adding attributes to category)

Source: Internet
Author: User
Tags uikit

Think of how you can add instance variables to all of your objects? We know that using category makes it easy to add methods to existing classes, but it is not possible to increase the instance variables directly. However, starting with Mac OS X v10.6, the system provides associative References, which is an easy problem to solve. This method is called Association (Association), we can dynamically add any number of properties during runtime, and read at any time. The two important runtime APIs used are:

1 objc_export  void   objc_setassociatedobject ( id  object,  const   void  *KEY,  id  value, Objc_associationpolicy Policy)
12 OBJC_EXPORT idobjc_getAssociatedObject(id object, const void*key)__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);

Now let's combine a practical example to illustrate their usage. Let's say we're now going to add the Flashcolor property by using the Category property supplement to Uilabel. In General, we have a principle: you can use category extension without inheritance, because with the increase in the depth of inheritance, code maintainability will increase a lot. use category to do this:

12345678 #import <UIKit/UIKit.h>#import <objc/runtime.h>@interface UILabel (Associate)//单单从头文件看是不是很像一个类?再看看.m文件你就知道这些都是假象了 - (nonatomic, retain) UIColor *FlashColor;@end
12345678910111213 #import "UILabel+Associate.h"@implementationUILabel (Associate)<br><br>@dynamicFlashColor;staticcharflashColorKey;- (void) setFlashColor:(UIColor *) flashColor{    objc_setAssociatedObject(self, &flashColorKey, flashColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (UIColor *) getFlashColor{   returnobjc_getAssociatedObject(self, &flashColorKey);}@end

The above example has several points to note:

1. Key: We notice that the type of key in the function signature is const void *, which means that key is just an address, not the contents of the string, which is also the reason why the Flashcolorkey is not initialized, because we don't care what the specific point is, All we need is the address! If you pass in Setassocaitedobject with Flashcolorkey, the Get method will be nil. The correct one should be the incoming address &flashcolorkey.

2. Policy: The policy here is the same as the retain, assign, and copy in the attribute declaration, no longer repeat

3. @dynamic declaration at the beginning of implement. In general @dynamic and @synthesize can be used to declare attributes, @synthesize is the default declaration, which means that the compiler automatically generates setters and getters for your properties during the compilation phase, while @dynamic tells the compiler, don't panic, boy, The compile phase does not generate a setter and getter for me, I have already implemented the setter and getter myself at runtime. Here we choose @dynamic. In fact, the two have aroused a strong controversy in StackOverflow: please click here.

Let's look at another example from Apple Guide:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 66676869707172737475767778798081828384858687 #import <Foundation/Foundation.h>#import <objc/runtime.h> intmain (intargc, constchar* argv[]) {     @autoreleasepool{    /*Seciton 0. 关联数据的Key和Value*/    staticcharoverviewKey;    staticconstchar*myOwnKey = "VideoProperty\0";    staticconstcharintValueKey = ‘i‘;     NSArray*array = [[NSArrayalloc]            initWithObjects:@ "One", @"Two", @"Three"nil];    // For the purposes of illustration, use initWithFormat: to ensure    // we get a deallocatable string    NSString*overview = [[NSStringalloc]            initWithFormat:@"%@", @"First three numbers"];    NSString*videoKeyValue = @"This is a video";    NSNumber*intValue = [[NSNumberalloc]initWithInt:5];    /*Section 1. 关联数据设置部分*/    objc_setAssociatedObject (            array,            &overviewKey,            overview,            OBJC_ASSOCIATION_RETAIN        );        [overview release];    objc_setAssociatedObject (        array,        myOwnKey,        videoKeyValue,        OBJC_ASSOCIATION_RETAIN    );     objc_setAssociatedObject (        array,        &intValueKey,        intValue,        OBJC_ASSOCIATION_RETAIN    );      /*Section 3. 关联数据查询部分*/    NSString*associatedObject =  (NSString*) objc_getAssociatedObject (array, &overviewKey);    NSLog(@"associatedObject: %@", associatedObject);    NSString *associatedObject2 = (NSString*) objc_getAssociatedObject(array, myOwnKey);    NSLog(@"Video Key value is %@", associatedObject2);    NSString*assObject3 = (NSString*) objc_getAssociatedObject(array, &myOwnKey);    if( assObject3 )    {        NSLog(@"不会进入这里! assObject3 应当为nil!");    }    else    {        NSLog(@"OK. 通过myOwnKey的地址是得不到数据的!");    }    NSNumber*assKeyValue = (NSNumber*) objc_getAssociatedObject(array, &intValueKey);    NSLog(@"Int value is %d",[assKeyValue intValue]);        /*Section 3. 关联数据清理部分*/    objc_setAssociatedObject (            array,            &overviewKey,            nil,            OBJC_ASSOCIATION_ASSIGN        );    objc_setAssociatedObject (        array,        myOwnKey,        nil,        OBJC_ASSOCIATION_ASSIGN    );        objc_setAssociatedObject (        array,        &intValueKey,        nil,        OBJC_ASSOCIATION_ASSIGN    );        [array release];     }    return0;}

Programming Little Weng @ Blog Park, thank you for your predecessor's information.

iOS Dynamics: How to add properties dynamically--association (e.g. adding attributes to category)

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.