MangoFix:iOS热修复另辟蹊径

作者 : 开心源码 本文共5371个字,预计阅读时间需要14分钟 发布时间: 2022-05-12 共315人阅读

??今天向大家详情的是iOS热修复的另一处理方案:MangoFix。详情他的起因是他和传统的iOS热修复使用JavaScript bridge 的方式完全不同,MangoFix是一个语法和OC语法非常相似的DSL,其语言本身的设计目标就是为理解决iOS热修复问题,所以在使用的便捷程度和性能方面都要远远超过传统的iOS 热修复SDK,比方JSPatch。下面从以下几点详情MangoFix,更具体的请参考GitHub文档和MangoFix单元测试。

1、如何加载一个MangoFix脚本

  • 1 首先通过CocoaPods安装MangoFix : pod 'MangoFix'
  • 2 引入MangoFix头文件:#import <MangoFix/MangoFix.h>
  • 3 创立MangoFix脚本执行上下文对象MFContext实例
  • 4 运行MangoFix脚本文件
    示例代码如下:
    NSString *path = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"mg"];    NSURL *scriptUrl = [NSURL fileURLWithPath:path];    MFContext *context = [[MFContext alloc] init];    [context evalMangoScriptWithURL:scriptUrl];

2、MangoFix如何修复OC对象(类)方法

??MangoFix可以替换或者创立任意OC对象实例方法或者类方法,语法和OC相似,不过在类的定义上采用class关键字。下面示例:

class MFInstanceMethodReplaceTest : NSObject {  - (BOOL)testInstanceMethodReplace{    return YES;}    }

对于类方法的替换只要将方法返回值类型前的-修改为+就可。
需要注意的是:
1、继承的父类不可以省略。

3、MangoFix如何为对象增加属性

??MangoFix中为对象增加属性和OC一样,支持的修饰符有: weakstrongcopyassignnonatomicatomic。下面看一下示例代码:

class MFObjectPropertyTest : NSObject{@property(nonatomic, copy)NSString *propertyName;  - (NSString *)testObjectPropertyTest{    return self.strTypeProperty;}}

需要注意的是:
1、属性不支持class修饰符。
2、MangoFix是通过objc_setAssociatedObject实现属性值的存储,但是MangoFix在解析时候做了解决,访问属性值也可以通过_propertyName这种方式进行访问。

4、MangoFix中如何使用block

??在MangoFix对OC中block类型公告过于复杂做了简化,用Block关键字表示block类型,block的定义则和OC相同,示例代码如下:

class MFMethodParameterListAndReturnValueTest : NSObject{- (Block)testMethodParameterListAndReturnValueWithString:(NSString *)str block:(Block)block{    NSMutableDictionary *dic = @{}.mutableCopy();    dic[@"param1"] = str + @"MangoFix";    dic[@"param2"] = block(@"MangoFix");        Block retBlock = ^NSDictionary *(/*不能加void*/){        return dic;    };    return retBlock;}}

需要注意的是:
1、在无参block定义时,不可以加void公告。
2、Block关键字后面不需要加*运算符。

5、如何处理Block循环引用问题

?? MangoFix在1.1.7版本中增加__weak__strong变量修饰符,可以像OC原生一样处理Block循环引用问题,使用示例如下:

@interface MyController : UIViewController@property(nonatomic,copy) id block;@end
class MyController: UIViewController {- (void)viewDidLoad {        super.viewDidLoad();        __weak id weakSelf = self;        self.block = ^{            __strong id strongSelf = weakSelf;            NSLog(weakSelf);        };}}

上部分是OC代码,下部分是MangoFix代码,需要注意的是,__weak__strong只能放在变量类型之前。

6、MangoFix中如何使用GCD

??MangoFix中已经内置的GCD API,使用方法和 OC相同,对于需要扩展的C函数,可以参考下面如何在MangoFix中注入全局对象的形容,GCD使用示例如下:

class MFGCDTest : NSObject {- (void)testGCDWithCompletionBlock:(Block)completion{    dispatch_queue_t queue = dispatch_queue_create("com.plliang19.mango", DISPATCH_QUEUE_SERIAL);    dispatch_async(queue, ^{        completion(@"success");    });}  }

7、如何在MangoFix中注入全局对象

??MangoFix中MFContext对象提供了 - (void)setObject:(MFValue *)value forKeyedSubscript:(NSObject <NSCopying> *)key;方法,便于客户向执行上下文中注入全局对象,比方在OC代码中执行下面代码:

context[@"globalVar"] = [MFValue valueInstanceWithBOOL:YES];context[@"MyLog"] = [MFValue valueInstanceWithBlock:^void (id obj){        NSLog(@"%@",obj);    }];

分别表示向context注入全局的BOOL变量globalVar和名为MyLog的block。

8、MangoFix中如何针对不同App版本做不同的热修复解决

??MangoFix提供了条件注解#If(conditionExpr),可以在运行时做判断注解所作用的类、属性、方法能否使能,先看一下示例代码:

class MFConditionalReplaceTest : NSObject{#If($systemVersion.doubleValue() >= 10.0 )- (BOOL)testConditionalReplace{    return NO;}}

上面代码表示只有当$systemVersion.doubleValue()值大于10.0才会对 - (BOOL)testConditionalReplace方法进行替换。 MangoFxi中已经内置了$systemVersion$appVersion$buildVersion等和版本相关的全局变量,分别表示:[UIDevice currentDevice].systemVersionCFBundleShortVersionStringCFBundleVersion,当然假如客户觉得不够还可以自己向MangoFix执行上下文中注入自己设置的全局变量。

9、MangoFix中自己设置结构体的使用要注意什么

??MangoFix脚本中使用结构体,准则上是要先对结构体使用declare struct进行公告,但是MangoFix已经对常用的结构已经内置公告,已内置公告的结构如下:
CGPointCGSizeCGRectCGAffineTransformCGVectorNSRangeUIOffsetUIEdgeInsetsCATransform3D

在MangoFix中使用未公告的结构体,需要做如下公告:

declare struct MFCustomStruct {    typeEncoding:"{MFCustomStruct=dd}",//@encode(struct MFCustomStruct)    keys:x,y}

特别需要注意的是:
1、在定义一个结构体变量时,需要在前面加入struct关键字:

  struct  UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

10、Masonry链式编程方式在MangoFix中如何编写

??有同学疑问对Masonry中的链式编程在MangoFix如何编写呢?其实这个写起来也是大同小异。需要注意的是,在MangoFix中对调用的方法假如是无参的,那么可以省去调用后面的一对括号,但是假如方法返回的是一个block对象,那么这对括号就不能省略,应为此时假如省略了方法调用括号,那么MangoFix解析器就无法知道,此时客户是想调用OC的对象方法,还是调用方法返回的block。下面是一个OC和MangoFix分别调用Masonry官方示例代码的比照:

    UIView *superview = self.view;    UIView *view1 = [[UIView alloc] init];    view1.translatesAutoresizingMaskIntoConstraints = NO;    view1.backgroundColor = [UIColor greenColor];    [superview addSubview:view1];    UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {        make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler        make.left.equalTo(superview.mas_left).with.offset(padding.left);        make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);        make.right.equalTo(superview.mas_right).with.offset(-padding.right);    }];
    UIView *superview = self.view;    UIView *view1 = UIView.alloc().init();    view1.translatesAutoresizingMaskIntoConstraints = NO;    view1.backgroundColor = UIColor.greenColor();    superview.addSubview:(view1);    struct  UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);    view1.mas_makeConstraints:(^(MASConstraintMaker *make) {        make.top.equalTo()(superview.mas_top).with.offset()(padding.top); //with is an optional semantic filler        make.left.equalTo()(superview.mas_left).with.offset()(padding.left);        make.bottom.equalTo()(superview.mas_bottom).with.offset()(-padding.bottom);        make.right.equalTo()(superview.mas_right).with.offset()(-padding.right);    });

上面部分是OC代码,下面部分是MangoFix代码,主要区别就是MangoFix代码在equalTooffset后面多了一对括号,就是避免MangoFix解析器产生歧义。再者就是MangoFix中UIEdgeInsets前的struct关键字不能省略。

11、MangoFix性能的如何

?? 根据本人测试,MangoFix的初始化速度是JSPatch的10倍左右,运行速度是JSPatch的2~5倍,内存占用方面并无太大区别。

12、MangoFix还有哪些不足

  • MangoFix不支持可变参数方法的调用和替换。
  • MangoFix调用C函数,需要预先通过注入全局对象方式,通过block将C函数预先埋入。
  • MangoFix不支持替换C函数。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » MangoFix:iOS热修复另辟蹊径

发表回复