打开Voice Over时,CATextLayer的string对象兼容NSString和NSAttributedString导致的Crash(二解决思路3)

续前一篇:
 打开Voice Over时,CATextLayer的string对象兼容NSString和NSAttributedString导致的Crash(二解决思路2)
ok,到这里已经能够锁定范围了,看看po $r0的打印结果:

再看看qzone的当前界面:

即布局第一条feeds的昵称时挂掉了。

经过追查昵称布局,发现同事写的一个class有些问题,废话不多说看代码:

@interface QZShimmeringLabel : UILabel
@property (nonatomic, strong) CATextLayer *textLayer;
...
@end

@implementation QZShimmeringLabel
- (NSAttributedString *)attributedText
{
    if ([self.textLayer.string isKindOfClass:[NSAttributedString class]])
    {
        return [self.textLayer.string string];
    }
    else
    {
        return nil;
    }
}

- (void)setAttributedText:(NSAttributedString *)attributedText
{
    self.textLayer.string = [attributedText copy];
}
...
@end
textLayer是CATextLayer类型,string是id类型:
@interface CATextLayer : CALayer
{
@private
  struct CATextLayerPrivate *_state;
}

/* The text to be rendered, should be either an NSString or an
 * NSAttributedString. Defaults to nil. */

@property(nullable, copy) id string;
...
@end
设置值时 self.textLayer.string 是 NSAttributedString 对象。读取时 返回了 NSAttributedString 的 string,是NSString类型:
@interface NSAttributedString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>

@property (readonly, copy) NSString *string;
- (NSDictionary<NSString *, id> *)attributesAtIndex:(NSUInteger)location effectiveRange:(nullable NSRangePointer)range;

@end
好了,问题查清楚了,就是这里的原因。

三、解决办法:

改前:
- (NSAttributedString *)attributedText
{
    if ([self.textLayer.string isKindOfClass:[NSAttributedString class]])
    {
        return [self.textLayer.string string];
    }
    else
    {
        return nil;
    }
}
改后:

- (NSAttributedString *)attributedText
{
    if ([self.textLayer.string isKindOfClass:[NSAttributedString class]])
    {
        return self.textLayer.string; // 去掉string调用
    }
    else
    {
        return nil;
    }
}


开发时同事稍微不注意,造成的一个笔误,结果害人不浅!!!


完结:

顺便说一句csdn真尼妈屎,一篇文章编辑完了,点发表成功,总是只能看到一部分,后面的被gou吃了,害老子写了半天的文章分好几部分才发完整。日〜〜〜


posted on 2015-09-19 21:59  封起De日子  阅读(169)  评论(0编辑  收藏  举报

导航