修改系统方法生命周期

参考文章

http://www.cocoachina.com/applenews/devnews/2014/0225/7880.html


Method swizzling指的是改变一个已存在的选择器对应的实现的过程,它依赖于Objectvie-C中方法的调用能够在运行时进改变——通过改变类的调度表(dispatch table)中选择器到最终函数间的映射关系。


举个例子,假设我们想跟踪在一个iOS应用中每个视图控制器展现给用户的次数:
 
我们可以给每个视图控制器对应的viewWillAppear:实现方法中增加相应的跟踪代码,但是这样做会产生大量重复的代码。子类化可能是另一个选择,但要求你将UIViewController、 UITableViewController、 UINavigationController 以及所有其他视图控制器类都子类化,这也会导致代码重复。
这时我们可以使用method swizzling

使用category也可以达到相同的效果
category(类别)。category可以对类进行扩展。当类别中的方法与原始方法名冲突时,类别具有更高的优先级,即会完全取代原始方法。
可以使用类别进行方法替换

上代码,找到一个既有的工程,将下面代码加入工程中,当绘制界面的时候(viewDidLoad),就会调用sdh_swizzlingMethod方法

//
//  SwizzlingMethod.h
//
//  Created by  songdh on 14-3-20.
//  Copyright (c) 2014年 xxxx. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface SwizzlingMethod : NSObject

@end


@interface UIViewController(package)

@end

//
//  SwizzlingMethod.m
//
//  Created by  songdh on 14-3-20.
//  Copyright (c) 2014年 xxx. All rights reserved.
//

#import "SwizzlingMethod.h"
#import <objc/runtime.h>

SEL originalSelector;
@implementation SwizzlingMethod

//originalSelector:被替换掉的方法
//origClass:originalSelector所在的类
//返回值:修改名字后的原始方法。
//使用时,若原始方法中包含有处理方法,那么将其替换后就会出错,可以在newSelector方法中调用replaceSelector的返回值方法。

+ (SEL)replaceSelector:(SEL)originalSelector OrigClass:(Class)origClass NewSelector:(SEL)newSelector NewClass:(Class)newClass
{
    Method originMethod = class_getInstanceMethod(origClass, originalSelector);
    IMP originImplementation = method_getImplementation(originMethod);
    const char *methodTypeEncoding = method_getTypeEncoding(originMethod);
    IMP newImplementation = [newClass instanceMethodForSelector:newSelector];
    
    NSString *selectorName = [NSString stringWithFormat:@"%@_%@", NSStringFromClass(origClass), NSStringFromSelector(originalSelector)];

    if (class_addMethod(origClass, NSSelectorFromString(selectorName), originImplementation, methodTypeEncoding)) {
        method_setImplementation(originMethod, newImplementation);
    }
    
    return NSSelectorFromString(selectorName);
}


+(void)load
{
    originalSelector = [SwizzlingMethod replaceSelector:@selector(viewDidLoad) OrigClass:[UIViewController class] NewSelector:@selector(sdh_swizzlingMethod) NewClass:[self class]];
}


- (void)sdh_swizzlingMethod
{
    [self performSelector:originalSelector withObject:nil];
    NSLog(@"%s",__FUNCTION__);
}

@end


@implementation UIViewController(package)
- (void)viewDidLoad
{
    NSLog(@"%s",__FUNCTION__);
}

@end





我创建了一个QQ群,希望大家能本着互联网开放的心态,将遇到的问题和经验在群里分享,大家互相交流心得,共同提高。
群号:77311380

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值