美文网首页
RunTime 之关联对象以及方法互换

RunTime 之关联对象以及方法互换

作者: 点滴86 | 来源:发表于2016-11-30 21:30 被阅读15次

    1.关联对象
    通过类别为已知类关联对象,与 Associated Objects 相关的函数主要有三个,声明如下:

    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)
    

    这三个函数的作用如下:
    objc_setAssociatedObject 用于给对象添加关联对象,传入nil 则可以移除已有的关联对象。
    objc_getAssociatedObject 用于获取关联对象。
    objc_removeAssociatedObjects 用于移除一个对象的所有关联对象。
    示例如下

    UIViewController+AssociatedObjects.h 代码

    #import <UIKit/UIKit.h>
    
    @interface UIViewController (AssociatedObjects)
    
    - (NSString*)author;
    
    - (void)setAuthor:(NSString*)name;
    
    @end
    

    UIViewController+AssociatedObjects.m 代码

    #import "UIViewController+AssociatedObjects.h"
    #import <objc/runtime.h>
    
    static char UIViewControllerAssociatedObjectAuthorKey;
    
    @implementation UIViewController (AssociatedObjects)
    
    - (NSString*)author
    {
        NSString *tempAuthor = @"";
        tempAuthor = objc_getAssociatedObject(self, &UIViewControllerAssociatedObjectAuthorKey);
        
        return tempAuthor;
    }
    
    - (void)setAuthor:(NSString *)name
    {
        objc_setAssociatedObject(self, &UIViewControllerAssociatedObjectAuthorKey, name, OBJC_ASSOCIATION_COPY);
    }
    
    @end
    
    

    使用如下:

    self.author = @"DianDi86";
     NSLog(@"%@",self.author);
    

    console log 如下

    logOne.png

    2.方法互换
    通过method_exchangeImplementations 实现方法互换.
    Vehicle.h

    #import <Foundation/Foundation.h>
    
    @interface Vehicle : NSObject
    
    - (void)testMethodSwizzling;
    
    @end
    

    Vehicle.m

    #import "Vehicle.h"
    
    @implementation Vehicle
    
    - (void)testMethodSwizzling
    {
        NSLog(@"Vehicle testMethodSwizzling Start");
        
        NSLog(@"Vehicle testMethodSwizzling End");
    }
    
    @end
    

    Car.h

    #import "Vehicle.h"
    
    @interface Car : Vehicle
    
    @end
    

    Car.m

    #import "Car.h"
    
    @implementation Car
    
    - (void)testMethodSwizzling
    {
        NSLog(@"Car testMethodSwizzling Start");
        
        [super testMethodSwizzling];
        
        NSLog(@"Car testMethodSwizzling End");
    }
    
    @end
    

    Vehicle+Replacement.h

    #import "Vehicle.h"
    
    @interface Vehicle (Replacement)
    
    @end
    

    Vehicle+Replacement.m

    #import "Vehicle+Replacement.h"
    #import <objc/runtime.h>
    
    @implementation Vehicle (Replacement)
    
    + (void)load
    {
        Method testMethodSwizzling_ = class_getInstanceMethod([self class], @selector(testMethodSwizzling));
        Method replacementTestMethodSwizzling_ = class_getInstanceMethod([self class], @selector(replacementTestMethodSwizzling));
        
        if (testMethodSwizzling_ && replacementTestMethodSwizzling_ && strcmp(method_getTypeEncoding(testMethodSwizzling_), method_getTypeEncoding(replacementTestMethodSwizzling_)) == 0) {
            method_exchangeImplementations(testMethodSwizzling_, replacementTestMethodSwizzling_);
        }
    }
    
    - (void)replacementTestMethodSwizzling
    {
        NSLog(@"replacementTestMethodSwizzling Start");
        
        [self replacementTestMethodSwizzling];
        
        NSLog(@"replacementTestMethodSwizzling End");
    }
    
    @end
    

    使用如下

    Car *audiA4L = [[Car alloc] init];
        [audiA4L testMethodSwizzling];
    

    console log 如下

    logTwo.png

    测试界面如下

    运行时功能.png

    相关文章

      网友评论

          本文标题:RunTime 之关联对象以及方法互换

          本文链接:https://www.haomeiwen.com/subject/yubtmttx.html