您的位置:首页 > 移动开发 > IOS开发

ios Method Swizzling学习笔记

2016-04-14 17:57 381 查看
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]));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios Method Swizzling