Giter Site home page Giter Site logo

joycerao / ocrunner Goto Github PK

View Code? Open in Web Editor NEW

This project forked from silverfruity/ocrunner

0.0 1.0 0.0 1.4 MB

OCRunner is a DSL using Objective-C syntax,OCRunner is also an iOS App hotfix SDK. You can use OCRunner method replace any Objective-C method. Lexer from https://github.com/SilverFruity/oc2mango, Executer modified from https://github.com/YPLiang19/Mango

License: MIT License

Objective-C 65.89% C 22.44% Swift 9.58% Ruby 0.12% Assembly 1.96%

ocrunner's Introduction

OCRunner

OCRunner is a DSL using Objective-C syntax,OCRunner is also an iOS App hotfix SDK. You can use OCRunner method replace any Objective-C method.

1. Demo运行

直接下载zip,是无法正常运行的。必须通过git clone

git clone --recursive https://github.com/SilverFruity/OCRunner.git

或者

git clone https://github.com/SilverFruity/OCRunner.git
cd OCRunner
git submodule update --init --recursive

OCRunner framework的单元测试已经转移到OCRunnerDemo下。

2. 功能

  • 将Objective-C作为脚本执行。

  • 86%的单元测试覆盖。

  • 支持全局C函数声明,直接获取函数指针。

  • 支持结构体。内置结构体内存布局,结构体取值与赋值等。

  • 支持枚举声明。

  • 可选libffi或者内置自定义实现的arm64 libff(基于TypeEncode不再是ffi_type)。

    默认使用libffi.a实现

    • 不使用libffi.a: 项目中移除的libffi文件夹的引用即可。
    • 使用libffi.a: 导入libffi文件夹即可。
  • 除去预编译、C数组声明、Protocol,其他语法皆已支持。

  • 支持可变参数函数和方法调用。

单元测试情况:

  1. iOS真机,无论是使用libffi.a或者是自定义的libffi,都是全通过的。
  2. iOS模拟器,单个测试运行是没有问题的,如果是Command+U运行,会出现测试不通过或者崩溃的情况。testCallFunctionPointer测试,在模拟器下,libffi调用偶尔会崩溃。

3. 与Objective-C当前存在的语法差异

3.1 预编译指令

不支持预编译指令 #define #if等

3.2 Protcol协议

当前不支持协议,不支持@protocol,但支持语法如下:

//这里实际创建的Classxxx并不遵循协议protocol1和protocol2
// [[Classxxx new] conformsToProtocol:@protocol(protocol1)] 必定为NO
@interface Classxxx: NSObject <protocol1, protocol2> 
@end
NSArray <NSObject*>*array;

3.3 类修复问题

  • 问题1: 我有个类有abcde5个方法以及若干属性,如果我只想对其中的A方法进行重写,我要把其他几个都带上吗? 答: 只需要重写A方法

3.3.1 已经存在的类

可以这么写,不用声明 @interface ORTestReplaceClass: SuperClass @end

@implementation ORTestReplaceClass
- (int)otherMethod{
    return 10;
}
- (int)test{
    return [self otherMethod];
}
@end

3.3.2 新建类

这里新建的ORTestReplaceClass类默认会继承自NSObject,如果你想添加property或者父类,就必须使用@interface

@implementation ORTestReplaceClass
- (int)otherMethod{
    return 10;
}
- (int)test{
    return [self otherMethod];
}
@end

3.3.3 支持分类写法

@implementation Demo
- (instancetype)initWithBaseUrl:(NSURL *)baseUrl{ }
- (NSString *)method2:(void(^)(NSString *name))callback{ }
@end
@implementation Demo (Category)
- (NSString *)method3:(void(^)(NSString *name))callback{ }
@end

3.4 关于枚举的一点问题

不支持NS_ENUMNS_OPTION,转换为对应的C声明方式即可.

例如:

typedef NS_OPTIONS(NSUInteger, UIControlEvents) {}
typedef NS_ENUM(NSUInteger, UIControlEvents) {}
// 需要转换为以下语法
typedef enum: NSUInteger {

}UIControlEvents;

3.5 关于结构体一点问题

被引用结构,必须提前声明

// CGPoint必须在CGRect之前声明
struct CGPoint { 
    CGFloat x;
    CGFloat y;
};
// CGSize必须在CGRect之前声明
struct CGSize { 
    CGFloat width;
    CGFloat height;
};
struct CGSize { 
    CGPoint point;
    CGSize size; 
};

3.6 UIKit中的常量、类型、结构体、枚举、全局函数的应对方法

3.6.1 常量、结构体、枚举

第一种:

// 需要在App中添加
// 结构体
ORStructDeclareTable *table = [ORStructDeclareTable shareInstance];
[table addStructDeclare:[ORStructDeclare structDecalre:@encode(CGPoint) keys:@[@"x",@"y"]]];
// 常量
[MFScopeChain.topScope setValue:[MFValue valueWithLongLong:DISPATCH_QUEUE_PRIORITY_HIGH] withIndentifier:@"DISPATCH_QUEUE_PRIORITY_HIGH"];

// 枚举值和常量相同
[MFScopeChain.topScope setValue:[MFValue valueWithULongLong:UIControlEventTouchDragInside] withIndentifier:@"UIControlEventTouchDragInside"];

第二种:

// 以下代码在脚本中直接添加即可
// 作用等同于上述的方式
typedef struct CGPoint { 
    CGFloat x;
    CGFloat y;
} CGPointss;
// 直接把UIControlEvents的定义复制过来,修改NS_OPTIONS即可
typedef enum: NSUInteger{
    UIControlEventTouchDown = 1 <<  0,
    UIControlEventTouchDownRepeat = 1 <<  1,
    UIControlEventTouchDragInside = 1 <<  2,
    UIControlEventAllTouchEvents = 0x00000FFF,
}UIControlEvents;
// 上述代码会新增了四个类型, dispatch_once_t, CGPoint, CGPointss, UIControlEvents
// 新增四个常量 UIControlEventTouchDown UIControlEventTouchDownRepeat UIControlEventTouchDragInside UIControlEventAllTouchEvents

id GlobalValue = [NSObject new]; //在OCRunner中是可以作为全局变量的

3.6.2 新增类型

typedef,目前还有typedef嵌套问题。

// 脚本中使用
typedef NSInteger dispatch_once_t;
// 脚本中使用
// 问题代码
typedef long long IntegerType;
typedef IntegerType dispatch_once_t;

3.6.3 全局函数

  1. 预编译函数
[MFScopeChain.topScope setValue:[MFValue valueWithBlock:^void(dispatch_queue_t queue, void (^block)(void)) {
		dispatch_async(queue, ^{
			block();
		});
	}] withIndentifier:@"dispatch_async"]
  1. 可通过ORSearchedFunction找的函数
// 直接在脚本中添加函数声明即可
void NSLog(NSString *format, ...);
  1. 不可通过ORSearchedFunction找的函数

    例如dispatch_get_main_queue

    • 方式一
    	[MFScopeChain.topScope setValue:[MFValue valueWithBlock:^id() {
    		return dispatch_get_main_queue();
     }]withIndentifier:@"dispatch_get_main_queue"];
    • 方式二
      //脚本中添加声明: DEBUG模式下会自动在控制台打印App中需要添加的代码
    dispatch_queue_main_t dispatch_get_main_queue(void);
    //App中添加: 
    [ORSystemFunctionTable reg:@"dispatch_get_main_queue" pointer:&dispatch_get_main_queue];
  2. OC中的inline函数、自定义函数

//脚本中直接添加
CGRect CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
{
  CGRect rect;
  rect.origin.x = x; rect.origin.y = y;
  rect.size.width = width; rect.size.height = height;
  return rect;
}

4. 关于#import

#import 是可以省略的。支持这个语法,仅仅是为了复制粘贴....

5. 不支持的语法

  • C数组声明:int a[x]等;

  • typeof

  • @optional

  • @encode

  • @synchronized

  • @try

  • @catch

  • @available

  • @protocol

  • @autoreleasepool

  • @dynamic

  • @synthesize

  • IBOutlet

  • IBAction

  • IBInspectable

强烈建议看看单元测试中支持的语法。

ocrunner's People

Contributors

silverfruity avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.