【问题标题】:Xcode 8.1 Command failed due to signal: Segmentation fault: 11Xcode 8.1 命令因信号而失败:分段错误:11
【发布时间】:2016-10-30 03:56:21
【问题描述】:

我已将我的应用升级到 Swift 3 和 Xcode 8.1。此更新后出现了一个令人费解的错误:FriendsViewController.swift 上的 Command failed due to signal: Segmentation fault: 11,但没有其他错误指示​​。

如何解决?

更新:添加 FriendsViewController 代码

import UIKit
import Contacts
import ContactsUI
import Firebase
import FBSDKCoreKit

// Allowing clean removal of objects
extension RangeReplaceableCollection where Iterator.Element : Equatable {

    // Remove first collection element that is equal to the given `object`:
    mutating func removeObject(_ object : Iterator.Element) {
        if let index = self.index(of: object) {
            self.remove(at: index)
        }
    }
}

// For searching
extension FriendsViewController: UISearchResultsUpdating {

    // must implement to conform to the UISearchResultsUpdating protocol.
    // As well as the scope narrowing
    func updateSearchResults(for searchController: UISearchController) {
        let searchBar = searchController.searchBar
        let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
        filterContentForSearchText(searchController.searchBar.text!, scope: scope)
    }
}

extension FriendsViewController: UISearchBarDelegate {
    // This delegate methods gets called when the user switches the scope in the scope bar.
    // When that happens, you want to redo the filtering,
    func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
        filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
    }
}

class FriendsViewController: UITableViewController, CNContactPickerDelegate  {

    // MARK: Properties
    var firebaseMainURL: String!
    @IBOutlet weak var menuButton: UIBarButtonItem!
    var contacts = [CNContact]()
    var friends: [Friend] = []
    var mappedFriends: [Friend] = []
    var filterMappedFriends: [Friend] = []
    var feastGlobalRef = FeastGlobal.sharedInstance
    let rootRef = FIRDatabase.database().reference()

    // Ensuring Serial queue
    let queue = DispatchQueue(label: "DISPATCH_QUEUE_SERIAL", attributes: [])

    // Adding search
    let searchController = UISearchController(searchResultsController: nil)

    override func viewDidLoad() {
        super.viewDidLoad()

        if revealViewController() != nil {
            menuButton.target = revealViewController()
            menuButton.action = #selector(SWRevealViewController.revealToggle(_:))
            view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())

        }

        // Creating the search bar, decides when to show and hide results
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true
        tableView.tableHeaderView = searchController.searchBar

        // Adding the scope bar and buttons:
        searchController.searchBar.scopeButtonTitles = ["All", "Friend", "A User", "Not User"]
        searchController.searchBar.delegate = self

        // Main mapping action
        self.mapContactsToPresentFriends(feastGlobalRef.userID)

    }

    override func viewWillAppear(_ animated: Bool) {
        //self.clearsSelectionOnViewWillAppear = self.splitViewController!.collapsed
        super.viewWillAppear(animated)
    }

    func findContacts() -> [CNContact] {
        let store = CNContactStore()

        let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
                           CNContactImageDataKey,
                           CNContactPhoneNumbersKey] as [Any]

        let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch as! [CNKeyDescriptor])

        var contacts = [CNContact]()

        do {
            try store.enumerateContacts(with: fetchRequest, usingBlock: { (contact, stop) -> Void in
                contacts.append(contact)
            })
        }
        catch let error as NSError {
            print(error.localizedDescription)
        }

        return contacts
    }

    // MARK: - Table View

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        if searchController.isActive && searchController.searchBar.text != "" {
            return filterMappedFriends.count
        }

        return self.mappedFriends.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let friend: Friend

        //let contact = contacts[indexPath.row] as CNContact
        let contact = mappedFriends[indexPath.row] as Friend

        // Getting phone number (default to first phone number present):
        let phoneNumber = contact.phoneNumber

        // If searching, then replace
        if searchController.isActive && searchController.searchBar.text != "" {
            friend = filterMappedFriends[indexPath.row]
        } else {
            friend = mappedFriends[indexPath.row]
        }

        // Conditional given relationship:
        var status: String!

        status = {
            switch friend.statusSort {
            case 0:
                return "Invite to Feast"
            case 1:
                return "Friend them"
            default:
                return "" // they are a friend
            }
        }()

        // Update the rows with the proper object
        cell.textLabel!.text = "\(friend.name) \(friend.userName)"
        cell.detailTextLabel?.text = "\(status)"
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        // Ensure controller knows which dataset to pull from,
        // so detail view is correct
        var friendChat: Friend!
        if searchController.isActive && searchController.searchBar.text != "" {
            friendChat = filterMappedFriends[indexPath.row]
        } else {
            friendChat = mappedFriends[indexPath.row]
        }

        // Now set the conditional cases: if a friend then chat, if user then friend request if not user then can invite them:
        if(friendChat.statusSort == 2) {

            self.performSegue(withIdentifier: "showIndividualChat", sender: self)

        } else if (friendChat.statusSort == 1) {

            let formatterShortDate = Date().dateStringWithFormat("yyyy-MM-dd HH:mm:ss")

            let myFriendPath = rootRef.child("friends").child(FeastGlobal.sharedInstance.userID)

            let friendFriendsPath = rootRef.child("friends").child(friendChat.userID)

            let friendInviteSync = rootRef.child("friendInviteNeedSync").child(friendChat.userID)

            //
            let friendsObject = [
                "confirmed" : true,
                "phoneNumber" : friendChat.phoneNumber,
                "selfSendRequest" : true,
                "timeInvited": formatterShortDate,
                "userName": friendChat.userName
            ]


            let myObject = [
                "confirmed" : true,
                "phoneNumber" : FeastGlobal.sharedInstance.phoneNumber,
                "selfSendRequest" : false,
                "timeInvited": formatterShortDate,
                "userName": FeastGlobal.sharedInstance.userName
            ]

            let friendInviteObject = [
                FeastGlobal.sharedInstance.userID : FeastGlobal.sharedInstance.userName
            ]

            queue.async {
                myFriendPath.child(friendChat.userID).setValue(friendsObject)
                friendFriendsPath.child(FeastGlobal.sharedInstance.userID).setValue(myObject)
                friendInviteSync.setValue(friendInviteObject)

            }

            queue.async {
                friendFriendsPath.child(FeastGlobal.sharedInstance.userID).setValue(myObject)
            }

            queue.async {
                self.mapContactsToPresentFriends(self.feastGlobalRef.userID)
            }


            print("Can invite to be friend")

        } else if (friendChat.statusSort == 0) {

            print("Invite to Feast")

        }
    }


    func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {
        let contact = contactProperty.contact
        let phoneNumber = contactProperty.value as! CNPhoneNumber

        print(contact.givenName)
        print(phoneNumber.stringValue)
    }

    // Method to match contacts with Firebase db friends:
    func mapContactsToPresentFriends(_ usersSyncID: String) {

        // Reset the data:
        self.mappedFriends.removeAll()
        self.friends.removeAll()

        // Use the queue (defined above) and "dispatch_async" to schedule the async actions, synchornously
        // First
        queue.async {
            print("start 1")

                self.contacts = self.findContacts()

            print("end 1")

        }

        // Second
        queue.async {

            let friendsURL = self.rootRef.child("friends").child(usersSyncID) // Firebase(url: firebaseMainURL + "friends/" + usersSyncID)

            var contactNumber: String?

            friendsURL.observeSingleEvent(of: .value, with: { snapshot in

                print("start 2")
                for oneSnapshot in snapshot.children {

                    for oneContact in self.contacts {

                        for oneContactPhoneNum in oneContact.phoneNumbers {

                            let phoneNumber = oneContactPhoneNum.value 

                            contactNumber = phoneNumber.stringValue

                            // Clean the number
                            let stringArray = contactNumber!.components(
                                separatedBy: CharacterSet.decimalDigits.inverted)
                            let newString = "1" + stringArray.joined(separator: "")

                            let firebaseFriendNumber = (oneSnapshot as AnyObject).value["phoneNumber"] as! String
                            print("Contacts number: " + newString)

                            print("Firebase number: " + firebaseFriendNumber)

                            if newString == firebaseFriendNumber {
                                print("friend added")

                                self.friends.append(Friend(userName: oneSnapshot.value["userName"] as! String,phoneNumber: firebaseFriendNumber, status: "Friend", statusSort: 2,  name: oneContact.givenName, userID: oneSnapshot.key))

                                // Remove that contact
                                self.contacts.removeObject(oneContact)
                            }
                        }
                    }
                }
                print("end 2")

                print("start 3")
                // Now do the users search:
                for oneContact in self.contacts {

                    var contactNumber: String

                    let phoneNumber = oneContact.phoneNumbers[0].value 

                    contactNumber = phoneNumber.stringValue

                    let stringArray = contactNumber.components(
                        separatedBy: CharacterSet.decimalDigits.inverted)
                    let newString = "1" + stringArray.joined(separator: "")

                    //let usersURL: Firebase! = Firebase(url: firebaseMainURL + "presentUserIDUserNameByPhoneNumber/" + newString)
                    let usersURL = self.rootRef.child("presentUserIDUserNameByPhoneNumber").child(newString)

                    // Check db:
                    usersURL.observeSingleEvent(of: .value, with: { snapshot in
                        print("start 3")

                        if snapshot.childrenCount > 1 {

                            // They are users (but not your friends), and remove yourself:
                            if(snapshot.value!["userID"] as! String != FeastGlobal.sharedInstance.userID) {

                                self.friends.append(Friend(userName: snapshot.value!["userName"] as! String, phoneNumber: snapshot.key, status: "A User", statusSort: 1, name: oneContact.givenName, userID: snapshot.value!["userID"] as! String))

                                let userName = snapshot.value!["userName"] as! String

                                print("Friends name: " + userName)

                            }

                        } else {

                            self.friends.append(Friend(userName: "", phoneNumber: phoneNumber.stringValue, status: "Not User", statusSort: 0, name: oneContact.givenName, userID: ""))

                        }

                        // Remove that contact
                        self.contacts.removeObject(oneContact)

                        // If all done, then sort and load main screen
                        if self.contacts.isEmpty {

                            self.mappedFriends = self.friends.sorted(by: {$0.statusSort > $1.statusSort})

                            self.tableView.reloadData()

                        }

                        print("end 3")

                    })
                }
            })
        }
    }

    func indexOfObject(_ object : AnyObject) -> NSInteger {
        return self.indexOfObject(object)
    }

    func friendRequestAction() {

        // TODO: Should siply be button to add friend, or request to feast.


    }

    // Results of search
    func filterContentForSearchText(_ searchText: String, scope: String = "All") {
        filterMappedFriends = mappedFriends.filter { Friend in
            let categoryMatch = (scope == "All") || (Friend.status == scope)
            return categoryMatch && Friend.name.lowercased().contains(searchText.lowercased())
        }

        tableView.reloadData()
    }

    // MARK: - Segues
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if let indexPath = tableView.indexPathForSelectedRow {

            // Ensure controller knows which dataset to pull from,
            // so detail view is correct
            let friendChat: Friend
            if searchController.isActive && searchController.searchBar.text != "" {
                friendChat = filterMappedFriends[indexPath.row]
            } else {
                friendChat = mappedFriends[indexPath.row]
            }

            // Now set the conditional cases: if a friend then chat, if user then friend request if not user then can invite them:

            if segue.identifier == "showIndividualChat" {

                let controller = segue.destination as! IndividualChatController
                controller.friendChat = friendChat
                controller.senderId = FeastGlobal.sharedInstance.userID
                controller.senderDisplayName = FeastGlobal.sharedInstance.userName
            }
        }
    }


    func getFriends() {

        let parametersfriend = ["fields": "name,picture.type(normal),gender"]

        FBSDKGraphRequest(graphPath: "me/friends", parameters: parametersfriend).start(completionHandler: { (connection, user, requestError) -> Void in
            if requestError != nil {
                print(requestError)
                return
            }

            print(user)

        })

    }
}

具体对象:

let friendsObject = [
    "confirmed" : true,
    "phoneNumber" : friendChat.phoneNumber,
    "selfSendRequest" : true,
    "timeInvited": formatterShortDate,
    "userName": friendChat.userName
]


let myObject = [
    "confirmed" : true,
    "phoneNumber" : FeastGlobal.sharedInstance.phoneNumber,
    "selfSendRequest" : false,
    "timeInvited": formatterShortDate,
    "userName": FeastGlobal.sharedInstance.userName
]

【问题讨论】:

  • 你能附上截图或有用的东西来解决这个错误吗?
  • @sohnryang 我添加了错误
  • friendsObject 和 myObject 字典对象的类型不正确。根据您使用 Swift 的上一个版本,他们对其进行了更改,并且您的代码可能假设该对象的值是别的东西。您现在需要将字典值显式转换为您期望从中获得的值。如果您从 FriendsViewController 发布代码,它将有助于告诉您如何正确投射对象
  • @JustinM 我通过添加视图更新了问题
  • 哇,你在那个 VC 中有多少行代码?你在哪里调用friendsObject和myObject?我浏览过一次,找不到你在哪里实现它们

标签: xcode segmentation-fault swift3


【解决方案1】:

有了 swift 的类型安全性,现在你上面的对象是 [String:Any] 类型的。当你尝试使用这些对象时,你需要告诉编译器你期望的类型是什么。

   let friendsObject: [String:Any] = [
        "confirmed" : true,
        "phoneNumber" : friendChat.phoneNumber,
        "selfSendRequest" : true,
        "timeInvited": formatterShortDate,
        "userName": friendChat.userName
    ]


    func doSomethingWith(FriendsObj: [String:Any] {
      guard let confirmed = friendsObject["confirmed"] as? Bool, 
      let phone = friendsObject["phoneNumber"] as? Int, 
      let sendRequest = friendsObject["selfSendRequest"] as? Bool else { return }

   //Now you can access confirmed, phone, and sendRequest as their native types.
 }

【讨论】:

  • 感谢您的回答,但除了myFriendPath.child(friendChat.userID).setValue(friendsObject),我没有使用它们,没有其他对这些对象的调用
  • 好的,抱歉,我无法提供更多帮助。您应该重新发布错误,这样如果其他人出现,他们就会解决这个问题。
  • 进一步研究指出这可能是 Xcode 版本中的一个错误。这没有理由失败......
  • 我选择注释掉整个 FriendsViewController,应用程序现在运行成功了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多