美文网首页日更
ios swizz的坑

ios swizz的坑

作者: 共田君 | 来源:发表于2019-06-12 14:25 被阅读0次

    ios中遇到一些难解的问题用swizz确实会比较方便的解决,比如批量换系统字体,比如AOP方式实现埋点,比如想为AB都有一个共同的基类C的方法,但是又因C没有公开方法,此时想为AB新增一个方法fun1,或修改C中的某一个方法,此时swizz可以解决这个问题。

    要注意几点

    1. 方法重复,比如如果本来在其他的catalog分类中已经有了一个方法fun1,此时想替换改类的fun2,这时候就容易出现混乱,导致无法预知执行的是那个fun1

    2. 被实现的方法必须是当前类方法,不能是父类方法,否则就不会执行父类方法了

    3. 交换的方法如果用到了cmd(当前方法的一个SEL指针),当cmd发生了变化,就无法保证系统方法内没有使用到cmd

    4. 在+load方法中替换,难保证其他方法是否也在执行,不会发生线程冲突导致失败

    文章完,大家自己可以做个试验看看效果吧

    
    @implementation ViewController(swizzz222)
     
    -(void)xxx_viewDidLoad{ 
        NSLog(@"xxx__222_viewDidLoad..."); 
        [self xxx_viewDidLoad]; 
    }
     
    @end
     
    @implementation ViewController(swizz)
     
    -(void)xxx_viewDidLoad{ 
        NSLog(@"xxx_viewDidLoad..."); 
        [self xxx_viewDidLoad]; 
    }
    
     
    -(void)yyy_viewDidLoad{
     
        NSLog(@"yyy_viewDidLoad...");
        [self yyy_viewDidLoad];
    }
     
    @end
    
    
    
    @implementation AppDelegate
     
    + (void)ht___replaceMethod:(Class)aClass originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector
    {
        Method originalMethod = class_getInstanceMethod(aClass, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector);
        BOOL didAddMethod =
    
        class_addMethod(aClass,
    
                        originalSelector,
    
                        method_getImplementation(swizzledMethod),
    
                        method_getTypeEncoding(swizzledMethod));
     
    
        if (didAddMethod) {
    
            NSLog(@"已经添加了 添加方法 class_replaceMethod %@",NSStringFromSelector(swizzledSelector));
    
            class_replaceMethod(aClass,
    
                                swizzledSelector,
    
                                method_getImplementation(originalMethod),
    
                                method_getTypeEncoding(originalMethod));
    
        } else {
    
            NSLog(@"没有添加成功,交换方法 method_exchangeImplementations %@",NSStringFromSelector(swizzledSelector));
    
            method_exchangeImplementations(originalMethod, swizzledMethod);
    
        }
    
    }
     
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
        // Override point for customization after application launch.
     
    //    [self.class htv___replaceMethod:ViewController.class originalSelector:@selector(viewDidLoad) swizzledSelector:@selector(xxx_viewDidLoad)];
    
    //    [self.class htv___replaceMethod:ViewController.class originalSelector:@selector(viewDidLoad) swizzledSelector:@selector(yyy_viewDidLoad)];
    
        [self.class htv___replaceMethod:ViewController.class originalSelector:@selector(viewDidAppear:) swizzledSelector:@selector(viewWillAppear:)];
    
        return YES;
    } 
    @end
    

    相关文章

      网友评论

        本文标题:ios swizz的坑

        本文链接:https://www.haomeiwen.com/subject/lbuhfctx.html