关于runtime的 class_addMethod 和 method_exchangeImplementations方法
//
// UIBarButtonItem+Public.m
// RuntimeDemo
//
// Created by huokr on 2/27/14.
// Copyright (c) 2014 huokr. All rights reserved.
//
#import "UIBarButtonItem+Public.h"
#import <objc/runtime.h>
@implementation UIBarButtonItem (Public)
/**/
- (id)initWithCustomTitle:(NSString *)title
style:(UIBarButtonItemStyle)style
target:(id)target
action:(SEL)action
{
___start_log___
self = [super init];
if (self) {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
CGRect frame = button.frame;
if (title) {
CGSize size = [title sizeWithFont:[UIFont boldSystemFontOfSize:16.0f]
constrainedToSize:CGSizeMake(MAXFLOAT, 16.0f)
lineBreakMode:(NSLineBreakByCharWrapping)];
[button setTitle:title
forState:(UIControlStateNormal)];
[button setTitleColor:[UIColor purpleColor]
forState:(UIControlStateNormal)];
button.titleLabel.font = [UIFont systemFontOfSize:16.0f];
if (size.width > 40) {
frame.size.width = size.width + 10;
button.frame = frame;
}
}
button.backgroundColor = [UIColor clearColor];
[button addTarget:target
action:action
forControlEvents:(UIControlEventTouchUpInside)];
self = [[UIBarButtonItem alloc] initWithCustomView:button];
}
return self;
}
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
//系统的原方法
// - (instancetype)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action;
SEL originalSelector = @selector(initWithTitle:style:target:action:);
SEL swizzledSelector = @selector(initWithCustomTitle:style:target:action:);
Method originalMethod =
class_getInstanceMethod(class,
@selector(initWithTitle:style:target:action:));
Method swizzledMethod =
class_getInstanceMethod(class,
@selector(initWithCustomTitle:style:target:action:));
//class_addMethod 参考 [这里写链接内容](http://longtimenoc.com/archives/ios%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E4%B8%BA%E7%B1%BB%E6%B7%BB%E5%8A%A0%E6%96%B9%E6%B3%95)
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
if (didAddMethod) {
___start_log___
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
//交换两个方法的实现!
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
/**/
@end
以上代码重载了load方法,其中利用oc 的 runtime机制把系统的initWithTitle:style:target:action:方法替换为自定义的initWithCustomTitle:style:target:action:
其中:
了解class_addMethod 参考 这里
本代码原作者地址:github