iOS - 记一次使用YYText,导致应用闪退

2019-01-14  本文已影响29人  不明Xia落

背景

绑定手机号

登录页面中,点击微信登录。未绑定手机号的情况下,会跳转到绑定手机号页面。在这个页面中的协议说明部分 中使用的是YYLabel,然后使用
- (void)yy_setTextHighlightRange:color: backgroundColor:tapAction:
实现事件的传递。

//创建协议视图
        _protocolL = [[YYLabel alloc] init];

        _protocolL.textColor = [RdAppSkinColor sharedInstance].secondaryTextColor;

        [self addSubview:_protocolL];

        NSString *protocolStr = [NSString stringWithFormat:@"登录后即同意《用户注册协议》与《隐私保护条款》"];

        NSMutableAttributedString *attrbutedprotocalBtn = [[NSMutableAttributedString alloc]initWithString:protocolStr];

        attrbutedprotocalBtn.yy_font = [UIFont systemFontOfSize:12];

        attrbutedprotocalBtn.yy_alignment = NSTextAlignmentCenter;

        NSRange rang = [protocolStr rangeOfString:@"《用户注册协议》"];

        NSRange rang2 = [protocolStr rangeOfString:@"《隐私保护条款》"];

        [attrbutedprotocalBtn yy_setTextHighlightRange:rang color:[RdAppSkinColor sharedInstance].mainColor backgroundColor:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
          //使用block向controller传递事件
            if (self.clickAction) {

                self.clickAction(@"用户注册协议");

            }

        }];

        [attrbutedprotocalBtn yy_setTextHighlightRange:rang2 color:[RdAppSkinColor sharedInstance].mainColor backgroundColor:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {

            if (self.clickAction) {

                self.clickAction(@"隐私保护条款");

            }

        }];

        _protocolL.attributedText = attrbutedprotocalBtn;

这段代码在我测试机iPhone6p 12.1.2 16G 以及 iPhone8 12.0 64G上面表现正常。在测试同事那边的iPhone6p 11.1.2 16G手机上为,反复点击协议跳转协议h5后返回,协议文案消失不见。

思路

1、文案消失,可能是我约束的时候没有给定这段文案的高度。于是给了这个文案20像素的高度


[_protocolL mas_makeConstraints:^(MASConstraintMaker *make) {

        make.centerX.equalTo(self).offset(0);

        make.top.equalTo(_loginButton.mas_bottom).offset(10);

        make.height.equalTo(@(20));

    }];

于是接着build,刚进入这个页面就闪退。。也没有进全局断点。

2、思考了一下,登录页面也使用了这个视图,但是没有出现闪退或者消失不见的问题。是在调用微信登录之后进入这个页面后才出现问题的。于是继续跑了一下,结果提示 Lost connection 。搜了一下出现这个提示的原因,意思大概是:应用程序很快分配了大量内存,操作系统终止了该应用程序。那是哪一个对象或者方法消耗了这么多的资源呢。我把目标瞄准了这个协议的文案使用的控件。

解决

1、使用UITextView替代YYLabel。使用textView的 链接的属性实现文字效果和点击事件


NSMutableAttributedString *protocolAttributedString = [[NSMutableAttributedString alloc] initWithString:@"登录后即同意《用户注册协议》与《隐私保护条款》"];

[protocolAttributedString addAttribute:NSLinkAttributeName

                        value:@"userRegisterProtocol://"

                        range:[[protocolAttributedString string] rangeOfString:@"《用户注册协议》"]];

[protocolAttributedString addAttribute:NSLinkAttributeName 

                        value:@"PrivacyProtection://" 

                        range:[[protocolAttributedString string] rangeOfString:@"《隐私保护条款》"]];

NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [RdAppSkinColor sharedInstance].mainColor,

                                NSUnderlineColorAttributeName:[RDAppskinColor sharedInstance].emphasisSubTextColor,

                                NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)};

textView.linkTextAttributes = linkAttributes; 

textView.attributedText = attributedString;

textView.delegate = self;

textView.editable = NO;

然后实现代理方法

- (BOOL)textView: shouldInteractWithURL: inRange:

但是这样有两点不好:

2、最终方案。使用UILabel,结合UITapGestureRecognizer,实现点击事件。

这里着重说一下点击事件的实现。让这个视图成为tap的UIGestureRecognizerDelegate委托者。

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapSelectProtocol:)];
    tap.delegate = self;
    [_protocolL addGestureRecognizer:tap];

实现


- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer {

    return YES;

}

这样就可以实现让tap的事件方法传递,根据点击位置实现不同事件的传递了。


- (void)tapSelectProtocol:(UITapGestureRecognizer*)tap {

    CGPointpoint = [taplocationInView:tap.view];

    NSString*title ;

    if(point.x>75&& point.x<160) {

        title =@"用户注册协议";

    }

    if(point.x>190&& point.x<282) {

        title =@"隐私保护条款";

    }

    if(title.length) {

        self.clickAction(title);

    }

//找到两个协议的大概位置。(这个位置相对于当前控件的)

//    NSLog(@"handleSingleTap!pointx:%f,y:%f",point.x,point.y);

}

build一下,重复 点击协议跳去协议详情web然后返回。没有异常。

反思

找到问题根源的方法具备偶然性。应该学会使用专门的检测工具Instruments来定位问题的所在。

上一篇下一篇

猜你喜欢

热点阅读