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

2016-11-30  本文已影响15人  点滴86

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
上一篇下一篇

猜你喜欢

热点阅读