打开Voice Over时,CATextLayer的string对象兼容NSString和NSAttributedString导致的Crash(二解决思路2)
ok,到这里已经能够锁定范围了,看看po $r0的打印结果:
![](https://i-blog.csdnimg.cn/blog_migrate/e539176398215210e7cf2959d77ef600.png)
再看看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吃了,害老子写了半天的文章分好几部分才发完整。日〜〜〜