iOS第三方库的填坑记录

本文记录了在iOS开发中遇到的第三方库问题,包括ReactiveCocoa的循环引用和支付宝SDK的retain cycle,以及MJRefresh刷新提示文本变为大写字母的解决办法。为开发者提供填坑参考。
摘要由CSDN通过智能技术生成

本文是本人平时开发遇到的三方库的填坑记录,仅做保存,如果有误导嫌疑,请无视我。

一、ReactiveCocoa

1、block是被控制器持有的,如果在block中使用self,会引起循环引用,控制器不能被释放掉,所以不是所有的三方库的block都是做了处理的。

block中,会引起循环引用有以下几种情况:

    //(1)在block中,使用self调用方法
    object.delegatrSignal = [RACSubject subject];
    [object.delegatrSignal subscribeNext:^(id x) {
        //使用self调用方法
        [self doSomething];
        
    }];
    //应使用weak修饰self,避免相互循环引用
    __weak typeof(self) weakSelf = self;
    object.delegatrSignal = [RACSubject subject];
    [object.delegatrSignal subscribeNext:^(id x) {
        //使用self调用方法
        [weakSelf doSomething];
        
    }];
    
    //(2)在block中,使用self的成员变量
    object.delegatrSignal = [RACSubject subject];
    [object.delegatrSignal subscribeNext:^(id x) {
        
        // 注:经过测试,在block中不通过self.property的方式调用,通过_property的方式调用,都会引起循环引用
        self.property;
        _property;
        
    }];
    //同样应使用weak修饰self,避免相互循环引用
    __weak typeof(self) weakSelf = self;
    object.delegatrSignal = [RACSubject subject];
    [object.delegatrSignal subscribeNext:^(id x) {
        
        weakSelf.property;
        
    }];
    
    //(3)在block中直接使用类的私有成员变量也会造成循环引用:
    //例如ViewController中有一个block类型的成员属性someBlock,另外一个是私有变量_children:
    @interface ViewController : UIViewController
    {
        NSObject *property;
    }
    @property (copy, nonatomic) void(^someBlock)();
    //其实在默认情况下,ViewController中的_children是使用__strong修饰的,上述情况就等价于下面的代码:
    @interface ViewController : UIViewController
    {
        __strong NSObject *property;
    }
    @property (copy, nonatomic) void(^someBlock)();
    //这个时候,在为someBlock赋值的时候,直接使用property就会造成retain cycle:
    self.someBlock = ^{
        property;
        // 上面代码就等价于下面一行
        // self->property;
    };
    //要打破此循环引用,也要用到(1)中使用的方法,不同的是,必须在block内使用__strong的self:
    __weak typeof(self) weakSelf = self;
    self.someBlock = ^{
        __strong typeof(weakSelf) strongSelf = weakSelf;
        strongSelf->property;
    };
    // __weakSelf在block里面有可能执行完一次被释放,所有要用__strong来确保在block内weakSelf不会被释放,但是此block内只有一句话,为什么要用__strong呢?因为用weakSelf->会引发这一种错误:Dereferencing a __weak pointer is not allowed due to possible null value caused by race condition, assign it to a strong variable first. (对一个 __weak 指针的解引用不允许的,因为可能在竞态条件里面变成 null, 所以先把他定义成 strong 的属性),所以必须用__strong来确保为强引用

注:

经过查阅资料,找到RAC下避免循环引用的方法:

#import "RACEXTScope.h"

- (void)viewDidLoad
{
    [super viewDidLoad];
    @weakify(self);
    [[NSNotificationCenter defaultCenter] addObserverForName:@"key" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
        @strongify(self);
        [self doSomething];
       // 如果使用到self的属性,不能用下划线_property,必须用self.property的方式
    }];
}


二、支付宝SDK

1、调用支付宝SDK跳转方法中的回调block中,也容易导致retain cycle,在回调block中不能直接使用self调用方法,或者直接使用成员变量和私有变量,调用方法如下:

[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
        

    }];

解决方法见上方ReactiveCocoa第一条。



2018.3.15更新

三、MJRefresh 刷新提示文本变为大写英文字母

在pod过的MJRefresh的项目中,Xcode9上,刷新提示文本变为大写英文字母,没有进行本地化处理。初步估计是本地化Localizable.strings文件在项目中没有成功加载。只有自己添加一遍来解决。

解决办法:

1、添加本地化文件 Localizable.strings,确保添加中英文。 添加方法

2、将一下文本复制在简体中文的文件中:

"MJRefreshHeaderIdleText" = "下拉可以刷新";

"MJRefreshHeaderPullingText" = "松开立即刷新";

"MJRefreshHeaderRefreshingText" = "正在刷新数据中...";


"MJRefreshAutoFooterIdleText" = "点击或上拉加载更多";

"MJRefreshAutoFooterRefreshingText" = "正在加载更多的数据...";

"MJRefreshAutoFooterNoMoreDataText" = "已经全部加载完毕";


"MJRefreshBackFooterIdleText" = "上拉可以加载更多";

"MJRefreshBackFooterPullingText" = "松开立即加载更多";

"MJRefreshBackFooterRefreshingText" = "正在加载更多的数据...";

"MJRefreshBackFooterNoMoreDataText" = "已经全部加载完毕";


"MJRefreshHeaderLastTimeText" = "最后更新:";

"MJRefreshHeaderDateTodayText" = "今天";

"MJRefreshHeaderNoneLastDateText" = "无记录";



。。。未完待续






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>