ios Method Swizzling学习笔记

Method Swizzling我的理解是运用Runtime获取类与类之间的方法,并且可以进行对换,从而达到某些目的,但是通过学习感觉和继承或者分类上使用父类的方法差不多,这种方式去搞,反而有点让接手的人不知所然,只是让外人觉得略微显得有点逼格一点。运行时可以对分类增加属性,在SDImageView中有大量使用,正常在分类中增加属性是无效的

   objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

学习代码创建三个类,

FOO、Bar、BarCategatory

#import <Foundation/Foundation.h>

@interface Foo : NSObject
- (void) testMethod;
- (void) baseMethod;
- (void) recursionMethod;

+ (BOOL)swizzleMethod:(SEL)origSel withMethod:(SEL)altSel;
+ (BOOL)swizzleClassMethod:(SEL)origSel withClassMethod:(SEL)altSel;

@end

//
//  Foo.m
//  AuditionTest
//
//  Created by xie on 16/4/14.
//  Copyright © 2016年 CJH. All rights reserved.
//

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

@implementation Foo
- (void) testMethod
{
    NSLog(@" >> Foo testMethod");
}

- (void) baseMethod
{
    NSLog(@" >> Foo baseMethod");
}

- (void) recursionMethod
{
    NSLog(@" >> Foo recursionMethod");
}
//交换方法
+ (BOOL)swizzleMethod:(SEL)origSel withMethod:(SEL)altSel
{
    Method origMethod = class_getInstanceMethod(self, origSel);
    if (!origSel) {
        NSLog(@"original method %@ not found for class %@", NSStringFromSelector(origSel), [self class]);
        return NO;
    }
    
    Method altMethod = class_getInstanceMethod(self, altSel);
    if (!altMethod) {
        NSLog(@"original method %@ not found for class %@", NSStringFromSelector(altSel), [self class]);
        return NO;
    }
    
    class_addMethod(self,
                    origSel,
                    class_getMethodImplementation(self, origSel),
                    method_getTypeEncoding(origMethod));
    class_addMethod(self,
                    altSel,
                    class_getMethodImplementation(self, altSel),
                    method_getTypeEncoding(altMethod));
    
    method_exchangeImplementations(class_getInstanceMethod(self, origSel), class_getInstanceMethod(self, altSel));
    
    return YES;
}

+ (BOOL)swizzleClassMethod:(SEL)origSel withClassMethod:(SEL)altSel
{
    Class c = object_getClass((id)self);
    return [c swizzleMethod:origSel withMethod:altSel];
}


@end
#import "Foo.h"

@interface Bar : Foo

- (void) testMethod;
@end

#import "Bar.h"

@implementation Bar
- (void) testMethod
{
    NSLog(@" >> Bar testMethod");
}
@end

#import "Bar.h"

@interface Bar (BarCategory)
- (void) altTestMethod;
- (void) altBaseMethod;
- (void) altRecursionMethod;
@end

#import "Bar+BarCategory.h"

@implementation Bar (BarCategory)
- (void) altTestMethod
{
    NSLog(@" >> Bar(BarCategory) altTestMethod");
}

- (void) altBaseMethod
{
    NSLog(@" >> Bar(BarCategory) altBaseMethod");
}

- (void) altRecursionMethod
{
    NSLog(@" >> Bar(BarCategory) recursionMethod");
    [self altRecursionMethod];
}
@end

main行数测试

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "Foo.h"
#import "Bar+BarCategory.h"
#import "Bar.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        
        @autoreleasepool
        {
            Foo * foo = [[Foo alloc] init];
            Bar * bar = [[Bar alloc] init];
            
            NSLog(@"========= Method Swizzling test 1 =========");
            
            NSLog(@" Step 1");
            [foo testMethod];
            [bar testMethod];
            [bar altTestMethod];
            
            NSLog(@" Step 2");
            [Bar swizzleMethod:@selector(testMethod) withMethod:@selector(altTestMethod)];
            [foo testMethod];
            [bar testMethod];
            [bar altTestMethod];
            
            NSLog(@"========= Method Swizzling test 2 =========");
            NSLog(@" Step 1");
            [foo baseMethod];
            [bar baseMethod];
            [bar altBaseMethod];
            
            NSLog(@" Step 2");
            [Bar swizzleMethod:@selector(baseMethod) withMethod:@selector(altBaseMethod)];
            [foo baseMethod];
            [bar baseMethod];
            [bar altBaseMethod];
            
            NSLog(@"========= Method Swizzling test 3 =========");
            [Bar swizzleMethod:@selector(recursionMethod) withMethod:@selector(altRecursionMethod)];
            [bar recursionMethod];
        }
        
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值