我的团队最近推出了一个应用程序,其中有很多SIGTRAP崩溃。以前我发现这些相对简单,因为它是在一个有问题的功能中找到一个不良的力量施放或一个隐含的未包裹的可选被设置为零的问题。这次虽然我找不到任何类似的东西。我最好的猜测是,由于日历错误,可能其中一个TimeBlock
对象或其属性为零。
我们的应用是一个会议组织者,根据FreeTime,Conflicts和Meeting TimeBlocks
向用户显示他们的原生iOS日历事件。我可以访问几个崩溃用户的日历。
Apple SigTrap定义
如果出现意外情况,Swift代码将以此异常类型终止 在运行时遇到条件,例如:
- 具有零值的非可选类型
- 强制类型转换失败
崩溃功能
/**
Updates the conflictHours and meetingHours according to the timeblocks
it is used as quick light reference to the button
*/
func updateTimeHours(timeblocks : [Timeblock]) {
for timeblock in timeblocks {
switch timeblock {
case is MeetingTimeblock:
for i in timeblock.startHour...timeblock.endHour {
self.meetingHours[i] = true
}
break
case is ConflictTimeblock:
for i in timeblock.startHour...timeblock.endHour {
self.conflictsHours[i] = true
}
break
default: break
}
}
updateButtonByOffset(offset: self.scrollTimeline.contentOffset.x)
}
调用崩溃功能
/**
This function inits the variables and button layout according to the timeblocks
*/
func handleTimeblocksDependantComponents() {
buttonLayout()
guard Scheduler.sharedInstance.timelines.count > SharedGlobals.Calendar.TODAY_INDEX else {
return
}
updateTimeHours(timeblocks : (Scheduler.sharedInstance.timelines[SharedGlobals.Calendar.TODAY_INDEX].timeblocks))
}
SetHeaderHeight
/**
Adjusts the height of the header depending on whether there are hosted meetings or
meeting VIP's or not.
*/
private func setHeaderHeight() {
self.tableView.tableHeaderView = self.headerView
let hostedMeetings = OverviewInteractor.getHostedMeetings(dayIndex: SharedGlobals.Calendar.SELECTED_DAY)
let vips = OverviewInteractor.getVIPS(dayIndex: SharedGlobals.Calendar.SELECTED_DAY)
self.tableView.beginUpdates()
if let headerView = self.tableView.tableHeaderView {
var height = 360.0
if(vips.count == 0) { height -= 80.0 }
if(hostedMeetings.count == 0) { height -= 80.0 }
headerView.frame.size.height = CGFloat(height)
}
self.tableView.endUpdates()
}
TimeBlock定义
// The Timeblock parent class. It simply holds a start and end time and provides its own duration. Not to be used as such
public class Timeblock {
public let startTime: Date
public let endTime: Date
/// Returns the hour the Timeblock starts, in current timezone
public var startHour: Int {
get {
return Calendar.current.component(.hour, from: startTime)
}
}
/// Returns the hour the Timeblocks ends, in current timezone
public var endHour: Int {
get {
return Calendar.current.component(.hour, from: endTime)
}
}
/// Returns the minutes the Timeblocks starts
public var startMinutes: Int {
get {
return Calendar.current.component(.minute, from: startTime)
}
}
/// Returns the minutes the Timeblocks ends
public var endMinutes: Int {
get {
return Calendar.current.component(.minute, from: endTime)
}
}
/**
Initialises the instance with a start and end time
- Parameters:
- startTime: The start time of the timeblock
- endTime: The end time of the timeblock
*/
public init(startTime: Date, endTime: Date) {
self.startTime = startTime
self.endTime = endTime
}
/**
Provides the Timeblock's duration in the form of a DateInterval
- warning: Only available on iOS 10.0 and up
- returns: A DateInterval of the duration of the Timeblock
*/
@available(iOS 10.0, *)
public func getTimeInterval() -> DateInterval {
return DateInterval(start: self.startTime, end: self.endTime)
}
/**
Provides the Timeblock's duration in the form of a `Double` (number of seconds)
- returns: The number of seconds that this Timeblock goes on for
*/
public func getDuration() -> Double {
return self.endTime.timeIntervalSince(self.startTime)
}
}
崩溃报告
事件标识符:98D4F477-C57B-4767-B957-E9EA2E0EE3EA CrashReporter密钥:0000000000000000000000000000000000000000硬件 型号:undefined进程:xxxxxxx [784]标识符:
com.xxx.xxx.xx.xxxxxxx版本:4.0.3代码类型:
arm64日期/时间:2017年12月24日星期日09:55:23 GMT + 0000(GMT)发布 时间:无效日期操作系统版本:未定义11.0.3 (15A432)报告版本:105
异常类型:SIGTRAP异常子类型:未定义
线程0名称:线程0崩溃:0 CallIn
0x0000000102c224e4专门 TimelineHeader.updateTimeHours(timeblocks :)(TimelineHeader.swift:0)1 CallIn 0x0000000102c20af0 TimelineHeader.handleTimeblocksDependantComponents() (TimelineHeader.swift:0)2 CallIn
0x0000000102c7a28c专门 MeetingTableViewController.tableView(:viewForHeaderInSection :) (TimelineHeader.swift:78)3 CallIn
0x0000000102c75d54 @objc MeetingTableViewController.tableView(:viewForHeaderInSection :) (MeetingTableViewController.swift:0)4 UIKit
0x000000018d1157d8 - [UITableView _delegateViewForHeaderInSection:] (UIKit)5 UIKit 0x000000018d11def0 96- [UITableView _sectionHeaderView:withFrame:forSection:floating:reuseViewIfPossible:willDisplay:] _ block_invoke (UIKit)6 UIKit 0x000000018cdf1a14 + [UIView(动画)performWithoutAnimation:](UIKit)7 UIKit 0x000000018d11dc60 - [UITableView _sectionHeaderView:withFrame:forSection:浮动:reuseViewIfPossible:willDisplay:] (UIKit)8 UIKit 0x000000018cfc6c04 - [_ UITableViewUpdateSupport(Private)_setupAnimationsForExistingHeadersAndFooters](UIKit)9 UIKit 0x000000018cfc1070 - [_ UITableViewUpdateSupport _setupAnimations] (UIKit)10 UIKit 0x000000018cfc0944 - [UITableView _updateWithItems:updateSupport:](UIKit)11 UIKit 0x000000018cfa8448 - [UITableView endCellAnimationsWithContext:] (UIKit)12 UIKit 0x000000018cfa46e4 - [UITableView endUpdates](UIKit)13 CallIn 0x0000000102c761a4 MeetingTableViewController.setHeaderHeight() (MeetingTableViewController.swift:398)14 CallIn
0x0000000102c7a7c8专门关闭#1 in MeetingTableViewController.refreshTable( :) (MeetingTableViewController.swift:513)15 CallIn
0x0000000102c7aacc部分申请封闭#1 MeetingTableViewController.refreshTable(_ :) (MeetingTableViewController.swift:0)16 CallIn
@callee_owned()的0x0000000102cd17f0 thunk - > () (LoginPageViewController.swift:0)17 libdispatch.dylib
0x000000018327ea54 _dispatch_call_block_and_release (libdispatch.dylib)18 libdispatch.dylib
0x000000018327ea14 _dispatch_client_callout(libdispatch.dylib)19 libdispatch.dylib 0x000000018328b698 _dispatch_main_queue_callback_4CF $ VARIANT $ mp(libdispatch.dylib)20 CoreFoundation 0x00000001838aa544 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE (CoreFoundation)21 CoreFoundation 0x00000001838a8120 __CFRunLoopRun (CoreFoundation)22 CoreFoundation
0x00000001837c7e58 CFRunLoopRunSpecific(CoreFoundation)23 GraphicsServices 0x0000000185674f84 GSEventRunModal (GraphicsServices)24 UIKit
0x000000018ce4767c UIApplicationMain(UIKit)25 CallIn
0x0000000102c02c08 main(AppDelegate.swift:18)26 libdyld.dylib
0x00000001832e456c start(libdyld.dylib)
答案 0 :(得分:0)
<强>生殖强>
这是由于Timeblock.startHour
和Timeblock.endHour
被Int
值混淆而引起的。在查看我们的用户日历后,我注意到他们所有人的会议都在午夜结束。
因此,对于在下午5点到午夜之间进行的会议,我们会发生以下情况。
for i in timeblock.startHour...timeblock.endHour
成为
for i in 0...17
这会给出一个非常精确的错误,告诉我一旦我重新发生崩溃就不能向后迭代,不幸的是崩溃报告中没有出现这种情况有点误导。
<强>修正强>
我们限制了创建timeblock.endHour
属性的时间,因此第二天的> 0:00
更改为23:59
以防止此情况发生。该修复只是将上限应用于>= 0:00
,因此在午夜结束的会议不会被视为多日会议。
未来的重构可能会设置从小时到前一小时结束的所有时间的结束时间,从技术上讲,如果您的会议在上午11:00结束,您仍然可以免费获得小时。我也想在Timeblock
对象中处理这一切,而不是过滤用于创建它的参数。