IOS Runtime app: associating objects

Source: Internet
Author: User

Before you begin, it is recommended that you read the basics of iOS Runtime: iOS Essentials: Runtime

There is a package in the interview, encountered such a question: "How to add a property to Nsarray (cannot use inheritance)", the package immediately forced, can not use inheritance, is it classified? But the classification can only add a method can not add properties Ah, the package is not the solution, until later came into contact with the runtime before it dawned.

What is an association object

An association object refers to an OC object that is connected to an instance of a class by a unique key.
For example: Xiaoming is an instance of the person class, and his dog (a OC object) is led by him through a string (key), which can be said that Xiaoming and dog are connected, of course xiaoming can lead multiple dog.

How to associate an object

The runtime provides us with the method:

//关联对象void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)//获取关联的对象id objc_getAssociatedObject(id object, const void *key)//移除关联的对象void objc_removeAssociatedObjects(id object)

Variable Description:

id object:被关联的对象(如xiaoming)const void *key:关联的key,要求唯一id value:关联的对象(如dog)objc_AssociationPolicy policy:内存管理的策略

The enum values for Objc_associationpolicy policy are:

OBJC_ASSOCIATION_ASSIGN = 0,          OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, OBJC_ASSOCIATION_COPY_NONATOMIC = 3,  OBJC_ASSOCIATION_RETAIN = 01401,       OBJC_ASSOCIATION_COPY = 01403

When the object is disposed, it is determined whether the associated object is disposed or not, and when the policy is retain/copy, the associated object is released (release), and when it is assign, it will not be freed.
It is important to note that we do not need to invoke removeassociated actively to contact the associated object, and if we need to deallocate the specified object, we can use Setassociatedobject to set nil.

Application of associated objects

1. Add Public properties

This is the most commonly used pattern, usually we will add attributes in the class declaration, but for some requirements (as described in the preface), we need to add one or more attributes in the classification, the compiler will error, the solution to this problem is to use the runtime's association object.
Application Examples:
We need to customize a tabbar and expose public properties and methods. (Readers can think of the advantages and disadvantages of using inheritance and classification implementations)

@interface UITabBarController (Custom)@property (nonatomic, strong) SUCustomTabbar * customTabbar;@end
#import "UITabBarController+Custom.h"#import <objc/runtime.h>@implementation UITabBarController (Custom)- (void)setCustomTabbar:(UIView *)customTabbar {    //这里使用方法的指针地址作为唯一的key    objc_setAssociatedObject(self, @selector(customTabbar), customTabbar, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (UIView *)customTabbar {    return objc_getAssociatedObject(self, @selector(customTabbar));}//其他方法...@end

In this way, we can use the custom tabbar like the native Tabbar:

[self.tabBarController.customTabbar doSomgthig];

2. Add a Private member variable

Sometimes, you need to add member variables in the taxonomy that you don't want to expose to public declarations.
Application Example: A callback to add a click time to a button

  @interface UIButton (Callback)-(Instancetype) initWithFrame: (CGRect) frame Callback: (void (^) (UIButton *)) Callbackblock; @end  
@interface UIButton ()@property (nonatomic, copy) void (^callbackBlock)(UIButton * button);@end@implementation UIButton (Callback)- (void (^)(UIButton *))callbackBlock {    return objc_getAssociatedObject(self, @selector(callbackBlock));}- (void)setCallbackBlock:(void (^)(UIButton *))callbackBlock {    objc_setAssociatedObject(self, @selector(callbackBlock), callbackBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);}- (instancetype)initWithFrame:(CGRect)frame callback:(void (^)(UIButton *))callbackBlock {    if (self = [super initWithFrame:frame]) {        self.callbackBlock = callbackBlock;        [self addTarget:self action:@selector(didClickAction:) forControlEvents:UIControlEventTouchUpInside];    }    return self;}- (void)didClickAction:(UIButton *)button {    self.callbackBlock(button);}@end

Readers think: Is there a memory management problem with the above code?

3. Associated KVO Observer
Sometimes we use KVO in classification, we recommend using the associated object as the observer, and try to avoid the object observing itself.
This application pattern is no longer an example, and interested readers can delve into it themselves or paste the code into a comment.

Thinking

1. More application patterns for related objects?
2. Is the associated object the first choice to solve the problem?
3. Side effects of associated objects?

You are welcome to exchange discussions.

Transferred from: http://www.jianshu.com/p/c68cc81ef763

IOS Runtime app: associating objects

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.