Skip to content

Instantly share code, notes, and snippets.

@CS2Us
Last active June 13, 2019 20:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CS2Us/93b39c7eef448c54352139c2fe88b22c to your computer and use it in GitHub Desktop.
Save CS2Us/93b39c7eef448c54352139c2fe88b22c to your computer and use it in GitHub Desktop.
Objective-C Method Swizzle 使用过程中需要注意的问题
//
// main.m
// testDispatch
//
// Created by guoyiyuan on 2019/6/6.
// Copyright © 2019 guoyiyuan. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Father : NSObject
-(void)work;
@end
@implementation Father
-(void)work{
NSLog(@"父亲得赚钱养家");
}
@end
@interface Son : Father
@end
@implementation Son
BOOL simple_Swizzle(Class aClass, SEL originalSel,SEL swizzleSel){
Method originalMethod = class_getInstanceMethod(aClass, originalSel);
Method swizzleMethod = class_getInstanceMethod(aClass, swizzleSel);
method_exchangeImplementations(originalMethod, swizzleMethod);
return YES;
}
BOOL best_Swizzle(Class aClass, SEL originalSel,SEL swizzleSel){
Method originalMethod = class_getInstanceMethod(aClass, originalSel);
Method swizzleMethod = class_getInstanceMethod(aClass, swizzleSel);
BOOL didAddMethod = class_addMethod(aClass, originalSel, method_getImplementation(swizzleMethod), method_getTypeEncoding(swizzleMethod));
if (didAddMethod) {
class_replaceMethod(aClass, swizzleSel, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
}else{
method_exchangeImplementations(originalMethod, swizzleMethod);
}
return YES;
}
@end
@CS2Us
Copy link
Author

CS2Us commented Jun 13, 2019

添加如下代码,结果会是怎样呢?

@implementation Son (Swizzle)

-(void)son_work{
	[self son_work];
	NSLog(@"son分类里的son_work");
}

+(void)load{
	NSLog(@"Swizzle 被调用");
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		simple_Swizzle([self class], NSSelectorFromString(@"work"), @selector(son_work));
	});
}

@end

int main() {
	Son *son = [Son new];
	[son work];
}

修改上面程序:

-(void)son_work{
	[self work];
	NSLog(@"son分类里的son_work");
}

导致的son_work递归调用问题如何解决:

  1. 修改son_work方法:
-(void)son_work{
	[self son_work];
	NSLog(@"son分类里的son_work");
}
  1. Son类中新增方法:
-(void)work{
	NSLog(@"破除循环调用");
}

@CS2Us
Copy link
Author

CS2Us commented Jun 13, 2019

添加以下代码,结果会是怎样呢?

@implementation Son (Swizzle_another)

+(void)load {
	NSLog(@"Swizzle_another 被调用");
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		simple_Swizzle([self class], NSSelectorFromString(@"work"), @selector(son_another_work));
	});
}

-(void)son_another_work {
	[self son_work];
	NSLog(@"son分类里的son_another_work");
}

@end

@implementation Son (Swizzle)

-(void)son_work{
	[self son_work];
	NSLog(@"son分类里的son_work");
}

+(void)load{
	NSLog(@"Swizzle 被调用");
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		simple_Swizzle([self class], NSSelectorFromString(@"work"), @selector(son_work));
	});
}

@end

int main() {
	Son *son = [Son new];
	[son work];
}

@CS2Us
Copy link
Author

CS2Us commented Jun 13, 2019

添加以下代码,结果会是怎样呢?

@implementation Son (Swizzle)

-(void)son_work{
	[self son_work];
	NSLog(@"son分类里的son_work");
}

+(void)load{
	NSLog(@"Swizzle 被调用");
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		simple_Swizzle([self class], NSSelectorFromString(@"work"), @selector(son_work));
	});
}

@end

@implementation Son (Swizzle_another)

+(void)load {
	NSLog(@"Swizzle_another 被调用");
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		simple_Swizzle([self class], NSSelectorFromString(@"work"), @selector(son_work));
	});
}

-(void)son_work {
	[self son_work];
	NSLog(@"son分类里的son_another_work");
}

@end

int main() {
	Son *son = [Son new];
	[son work];
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment