Swift“专业”崩溃

Posted

技术标签:

【中文标题】Swift“专业”崩溃【英文标题】:Swift "Specialized" Crash 【发布时间】:2016-05-14 21:22:29 【问题描述】:

下面是我的一个应用程序中不断发生的崩溃的堆栈跟踪。我不知道如何解决它,它并不总是发生?请帮忙:)

它与 Swift 泛型有关吗?

    Thread : Crashed: com.apple.main-thread
0  MyApp                         0x1000f4f5c specialized FriendsTableViewController.tableView(UITableView, cellForRowAtIndexPath : NSIndexPath) -> UITableViewCell (FriendsTableViewController.swift)
1  MyApp                         0x1000f1f60 @objc FriendsTableViewController.tableView(UITableView, cellForRowAtIndexPath : NSIndexPath) -> UITableViewCell (FriendsTableViewController.swift)
2  UIKit                          0x1867ad31c -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 692
3  UIKit                          0x1867ad484 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 80
4  UIKit                          0x18679c9b8 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2824
5  UIKit                          0x186539208 -[UITableView _setNeedsVisibleCellsUpdate:withFrames:] + 240
6  UIKit                          0x1865390d0 -[UITableView _rectChangedWithNewSize:oldSize:] + 996
7  UIKit                          0x186546df4 -[UITableView setBounds:] + 256
8  UIKit                          0x18647a2bc -[UIScrollView setContentOffset:] + 424
9  UIKit                          0x1865382bc -[UITableView setContentOffset:] + 300
10 UIKit                          0x186780a3c -[UIScrollView(UIScrollViewInternal) _adjustContentOffsetIfNecessary] + 60
11 UIKit                          0x18677ab5c -[UIScrollView _updateForChangedScrollRelatedInsets] + 48
12 UIKit                          0x18651d5ac -[UIScrollView setContentInset:] + 116
13 UIKit                          0x186546c50 -[UITableView setContentInset:] + 132
14 UIKit                          0x1865bf250 -[UIScrollView(UIScrollViewInternal) _adjustForAutomaticKeyboardInfo:animated:lastAdjustment:] + 348
15 UIKit                          0x1865bf0b8 -[UITableView _adjustForAutomaticKeyboardInfo:animated:lastAdjustment:] + 108
16 UIKit                          0x186d50380 -[UIAutoRespondingScrollViewControllerKeyboardSupport _adjustScrollViewForKeyboardInfo:] + 288
17 Foundation                     0x18211e44c __NSFireDelayedPerform + 428
18 CoreFoundation                 0x1817215f4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28
19 CoreFoundation                 0x181721298 __CFRunLoopDoTimer + 884
20 CoreFoundation                 0x18171e9ac __CFRunLoopRun + 1520
21 CoreFoundation                 0x18164d680 CFRunLoopRunSpecific + 384
22 GraphicsServices               0x182b5c088 GSEventRunModal + 180
23 UIKit                          0x1864c4d90 UIApplicationMain + 204
24 MyApp                         0x100094ef8 main (AppDelegate.swift:15)
25 libdispatch.dylib              0x1811ee8b8 (Missing

除此之外,这是我拥有的 cellForRow 函数

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    if indexPath.section < 2 
        let cell = tableView.dequeueReusableCellWithIdentifier("FriendCell", forIndexPath: indexPath) as! FriendTableViewCell
        cell.tag = indexPath.row

        var user: TetherUser!

        if searching 
            user = searchedUsers[indexPath.row]
         else 
            if indexPath.section == 0 
                user = users[indexPath.row]
                cell.actionButton.friendIsContact = false
             else if indexPath.section == 1 
                user = contactsWithApp[indexPath.row]
                cell.actionButton.friendIsContact = true
            
        

        user.tag = indexPath.row

        cell.nameLabel.text = user.fullName
        cell.profileImageView.image = nil
        user.profileImage  (image) -> Void in
            if user.tag == cell.tag 
                cell.profileImageView.image = image
            
        

        if let currentUserID = TetherManager.sharedInstance.currentTetherUser?.objectId 
            cell.actionButton.type = user.relationToUserWithID(currentUserID)
            cell.actionButton.tag = indexPath.row
            cell.actionButton.delegate = self
            switch user.relationToUserWithID(currentUserID) 
            case .None:
                cell.actionButton.button.setImage(UIImage(named: "AddFriend"), forState: .Normal)
                break
            case .SentFriendRequest:
                cell.actionButton.button.setImage(UIImage(named: "ReceivedFriendRequest"), forState: .Normal)
                break
            case .ReceivedFriendRequest:
                cell.actionButton.button.setImage(UIImage(named: "PendingFriendRequest"), forState: .Normal)
                break
            case .Friends:
                cell.actionButton.button.setImage(UIImage(named: "RemoveFriend"), forState: .Normal)
                break
            
        
        return cell
     else 
        //Contacts
        let cell = tableView.dequeueReusableCellWithIdentifier("ContactCell", forIndexPath: indexPath) as! ContactTableViewCell
        cell.contact = addressBookContacts[indexPath.row]
        cell.delegate = self
        return cell
    

【问题讨论】:

您的表格视图中有多少个部分? @Shripada 抱歉 3 个部分 好的,现在很清楚它为什么会崩溃了。请注意,您没有为案例 indexPath.section == 2 加载用户对象。处理它。 我遇到了同样的错误。关于您如何解决问题的任何建议? 【参考方案1】:

您需要为 indexPath.section == 2 时的情况创建用户对象,因为您有 3 个部分。您需要确保在此代码块中正确初始化了“用户”对象(请参阅代码中的内联注释)

    var user: TetherUser!

    if searching 
        user = searchedUsers[indexPath.row]
     else 
        if indexPath.section == 0 
            user = users[indexPath.row]
            cell.actionButton.friendIsContact = false
         else if indexPath.section == 1 
            user = contactsWithApp[indexPath.row]
            cell.actionButton.friendIsContact = true
         else if indexPath.section == 2 
         // Add code here to ensure user has proper value.
        
    

【讨论】:

我只是觉得奇怪的是这种不一致的发生方式。 1. 专业是什么意思 2.为什么我不会在堆栈跟踪中得到“索引越界”? @shripada 不是索引越界问题。诚然,如果您正在访问一个未初始化的隐式展开的 var,那么该崩溃日志可能会更有帮助。 我不知道这实际上是问题所在。 OP 在 cellForRowAtIndexPath 中做的第一件事是检查indexPath.section &lt; 2,这样就不会触发额外的else if 同意@ThiagoCampezzi。这不会解决任何问题。【参考方案2】:

我也有这个“专业”错误。崩溃仅发生在 ios 8.0 和 8.1 上。这是我的堆栈跟踪的一部分。

Crashed: com.apple.main-thread
0  Viki                           0x10027bb28 specialized LoginFlowSocialButton.traitCollectionDidChange(UITraitCollection?) -> () + 4297243432
1  Viki                           0x10027ad30 @objc LoginFlowSocialButton.traitCollectionDidChange(UITraitCollection?) -> () (LoginFlowButton.swift)
2  UIKit                          0x18a696cd4 -[UIView _processTraitsDidChangeRecursively:forceNotification:] + 124
3  UIKit                          0x18a3d05f4 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 348
4  UIKit                          0x18a3d0408 -[UIView(Hierarchy) _postMovedFromSuperview:] + 484
5  UIKit                          0x18a3dbea4 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1724
6  UIKit                          0x18a694f34 -[UIView initWithCoder:] + 756
...

我尝试下载具有这些版本的 iOS 模拟器之一并再次测试。原来崩溃是由于使用了强制解包的 var 但在 traitCollectionDidChange 函数中找到了 nil

所以这里的教训只是错误消息中的specialized 函数可能没有指向确切的问题。您可以尝试更多地研究该函数,看看那里出了什么问题。

希望对您有所帮助。 :)

【讨论】:

以上是关于Swift“专业”崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Swift SourceKitService 崩溃

如何使用 swift 检测应用程序崩溃?

Crashlytics iOS - 第 0 行崩溃 - Swift 来源

Swift3 - 视觉格式约束崩溃

Swift 4:@IBOutlet UITextView 崩溃

@objc 协议使 swift 编译器崩溃