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

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 5,896评论 0 9
  • 继上Runtime梳理(四) 通过前面的学习,我们了解到Objective-C的动态特性:Objective-C不...
    小名一峰阅读 4,160评论 0 3
  • 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的...
    lylaut阅读 4,241评论 0 4
  • 转载:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麦子阅读 4,145评论 0 2
  • 本文转载自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex阅读 4,214评论 0 1

友情链接更多精彩内容