Method Swizzling 的一个使用场景

很早就看过一些关于 Method Swizzling 的博客,看完后一直没有一个恰当的使用场景能操练一下。最近写一个 Demo 的时候发现要在很多控制器里写导航栏的返回按钮,本来是复制一下或者继承一下就行的。但是复制这种做法挺蠢的,继承会让代码耦合性增加。这个时候我就突然的想到了 Method Swizzling,然后做了一个尝试。

创建一个 UIViewController 的分类,引入#import <objc/runtime.h>头文件。基本代码如下:

@implementation UIViewController (BackButton)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
    
        SEL originalSelector = @selector(viewWillAppear:);
        SEL swizzledSelector = @selector(swizzled_viewWillAppear:);
    
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
        BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
    
        if (didAddMethod) {
            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

#pragma mark - Method Swizzling
- (void)swizzled_viewWillAppear:(BOOL)animated {
    [self swizzled_viewWillAppear:animated];
    
    //在这里判断哪个控制器不需要返回按钮
    if (![self isMemberOfClass:NSClassFromString(@"ViewController")]) {
        UIImage *image = [UIImage imageNamed:@"goBack_blue.png"];
        UIButton *leftButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
        [leftButton setImage:image forState:UIControlStateNormal];
        [leftButton addTarget:self action:@selector(goBack) forControlEvents:UIControlEventTouchUpInside];
        UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton];
        self.navigationItem.leftBarButtonItem = leftBarButtonItem;
    }

    NSLog(@"swizzled_viewWillAppear");
}

- (void)goBack {
    [self.navigationController popViewControllerAnimated:YES];
}

@end

这样就实现了,下篇见~

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

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 5,865评论 0 9
  • 文中的实验代码我放在了这个项目中。 以下内容是我通过整理[这篇博客] (http://yulingtianxia....
    茗涙阅读 4,470评论 0 6
  • 转载:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麦子阅读 4,119评论 0 2
  • 本文转自:杨萧玉博客 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C ...
    oneofai阅读 1,580评论 0 0
  • 继上篇安装使用教程,在这里写一下可能会遇到的问题:这个也是最坑的地方,有些我有遇到,有些没有,在这里整理了下,心累...
    你的小福蝶阅读 4,084评论 0 1

友情链接更多精彩内容