iOS SIGSEGV SEGV_ACCERR崩溃layoutSubviews
问题描述:
我的应用程序有时会在layoutSubview方法中崩溃。它发生在应用程序计算UITableViewCell的高度时。有时应用程序崩溃,并不总是。这里的功能代码:iOS SIGSEGV SEGV_ACCERR崩溃layoutSubviews
+ (CGFloat)heightForEditorialCommentData:(EditorialCommentVMData *)editorialData
{
EditorialCommentCell * cell = [EditorialCommentCell instanceCell];
[cell applyViewModelData:editorialData];
[cell layoutSubviews];
return cell.commentTextLabel.frameBottom + kTextInsets.bottom;
}
+ (EditorialCommentCell *)instanceCell {
static EditorialCommentCell *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSArray *views = [[NSBundle mainBundle] loadNibNamed: @"EditorialCommentCell" owner:0 options:0];
instance = views[0];
instance.frame = CGRectMake(instance.contentView.frame.origin.x,
instance.contentView.frame.origin.y,
[[UIScreen mainScreen] bounds].size.width,
instance.contentView.frame.size.height);
});
return instance;
}
下面是堆栈跟踪:
Thread : Crashed: com.apple.root.default-qos
0 UIKit 0x2ff92b3a -[_UIViewAdditiveAnimationAction runActionForKey:object:arguments:] + 569
1 UIKit 0x2ff92cf5 __67-[_UIViewAdditiveAnimationAction runActionForKey:object:arguments:]_block_invoke + 408
2 QuartzCore 0x2f71e4c5 CA::Layer::end_change(CA::Transaction*, unsigned int, objc_object*) + 96
3 QuartzCore 0x2f71f06b CA::Layer::set_bounds(CA::Rect const&, bool) + 530
4 QuartzCore 0x2f71ed87 -[CALayer setBounds:] + 110
5 UIKit 0x3017f84f -[_UILabelLayer setBounds:] + 58
6 QuartzCore 0x2f71fe01 -[CALayer setFrame:] + 600
7 UIKit 0x3017f7eb -[_UILabelLayer setFrame:] + 58
8 UIKit 0x2fcfc4d7 -[UIView(Geometry) setFrame:] + 254
9 UIKit 0x2fd09f53 -[UILabel setFrame:] + 138
CRASH->10 MYAPP 0x000fb611 -[UIView(Frame) setFrameWidth:] (UIView+Frame.m:103)
11 MYAPP 0x00130c75 -[EditorialCommentCell layoutSubviews] (EditorialCommentCell.m:139)
12 MYAPP 0x001324ed +[EditorialCommentCell heightForEditorialCommentData:] (EditorialCommentCell.m:351)
13 MYAPP 0x00115733 -[EditorialCommentsViewModel applyDataFromItem:toVMItem:] (EditorialCommentsViewModel.m:298)
14 MYAPP 0x00114e73 -[EditorialCommentsViewModel vmDataFromItem:] (EditorialCommentsViewModel.m:222)
15 MYAPP 0x000fac29 -[FatherViewModel insertItemsUpdatingExisting:intoVMItems:] (FatherViewModel.m:418)
16 MYAPP 0x000f9cfd __39-[FatherViewModel updateItems:failure:]_block_invoke_3 (FatherViewModel.m:281)
17 libdispatch.dylib 0x3a4718cb _dispatch_call_block_and_release + 10
18 libdispatch.dylib 0x3a47ada3 _dispatch_root_queue_drain + 834
19 libdispatch.dylib 0x3a47bcd7 _dispatch_worker_thread3 + 94
20 libsystem_pthread.dylib 0x3a5d2e31 _pthread_wqthread + 668
这里我layoutSubview代码:
- (void)layoutSubviews {
[super layoutSubviews]; // Sometimes crashed here
CGFloat contentLeft = kTextInsets.left;
BOOL isReply = self.editorialCommentData.inReplyToCommentId != 0;
if (isReply) {
contentLeft += kAuthorLeftInset + self.authorImageView.frameWidth;
}
self.authorImageView.frameOrigin = CGPointMake(contentLeft, kContentInsets.top);
self.votesLabel.frameWidth = 200; // Sometimes crashed here
[self.votesLabel sizeToFit];
self.votesLabel.frameTop = self.authorImageView.frameTop - 1.5f;
self.votesLabel.frameRight = self.contentView.bounds.size.width - kContentInsets.right;
<.....more code here.....>
}
我认为这是内存管理的问题。
答
好的!我修好了它。从Marco关于layoutSubviews方法的评论:“你不应该直接调用这个方法。如果你想强制布局更新,改用setNeedsLayout方法在下一次更新图纸之前调用。” 我只是改变layoutSubviews到layoutIfNeeded方法:
+ (CGFloat)heightForEditorialCommentData:(EditorialCommentVMData *)editorialData
{
EditorialCommentCell * cell = [EditorialCommentCell instanceCell];
[cell applyViewModelData:editorialData];
[cell layoutIfNeeded];
return cell.commentTextLabel.frameBottom + kTextInsets.bottom;
}
从苹果文档中关于layoutIfNeeded:
使用此方法强制子视图的布局图前。使用 接收该消息作为根视图的视图,此方法将 从根处开始的视图子树排除。
我不知道它是否与你的问题有关,但是关于layoutSubviews方法,Apple文档说“你不应该直接调用这个方法,如果你想强制布局更新,改用setNeedsLayout方法在下一次更新图纸之前这样做。“ – 2014-10-09 08:27:21
@MarcoPace哦,谢谢,我现在就试试吧! – ItsTipTop 2014-10-09 08:32:00