ios - 没有构建错误,但在模拟器中崩溃。

标签 ios swift ios-simulator xcode8.2

我没有收到构建错误,但是一旦我进入模拟器并按右上角的 + 添加新的 url,程序就会崩溃。这是我得到的错误:

2017-02-21 09:37:48.667 Favorite Websites[2211:128142] ->[Favorite_Websites.MasterViewController addButtonPressed:]: unrecognized selector sent to instance 0x7ff266408aa0 2017-02-21 09:37:48.672 Favorite Websites[2211:128142] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Favorite_Websites.MasterViewController addButtonPressed:]: unrecognized selector sent to instance 0x7ff266408aa0' * First throw call stack: ( 0 CoreFoundation 0x000000010d0b0d4b exceptionPreprocess + 171 1 libobjc.A.dylib 0x000000010cb1221e objc_exception_throw + 48 2 CoreFoundation 0x000000010d120f04 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132 3 CoreFoundation 0x000000010d036005 ___forwarding_ + 1013 4 CoreFoundation 0x000000010d035b88 _CF_forwarding_prep_0 + 120 5 UIKit 0x000000010d4d68bc -[UIApplication sendAction:to:from:forEvent:] + 83 6 UIKit 0x000000010d9184a1 -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 149 7 UIKit 0x000000010d4d68bc -[UIApplication sendAction:to:from:forEvent:] + 83 8 UIKit 0x000000010d65cc38 -[UIControl sendAction:to:forEvent:] + 67 9 UIKit 0x000000010d65cf51 -[UIControl _sendActionsForEvents:withEvent:] + 444 10 UIKit 0x000000010d65d0db -[UIControl _sendActionsForEvents:withEvent:] + 838 11 UIKit 0x000000010d65be4d -[UIControl touchesEnded:withEvent:] + 668 12 UIKit 0x000000010d544545 -[UIWindow _sendTouchesForEvent:] + 2747 13 UIKit 0x000000010d545c33 -[UIWindow sendEvent:] + 4011 14 UIKit 0x000000010d4f29ab -[UIApplication sendEvent:] + 371 15 UIKit 0x000000010dcdf72d dispatchPreprocessedEventFromEventQueue + 3248 16 UIKit 0x000000010dcd8463 __handleEventQueue + 4879 17 CoreFoundation 0x000000010d055761 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 18 CoreFoundation 0x000000010d03a98c __CFRunLoopDoSources0 + 556 19 CoreFoundation 0x000000010d039e76 __CFRunLoopRun + 918 20 CoreFoundation 0x000000010d039884 CFRunLoopRunSpecific + 420 21 GraphicsServices 0x000000011173fa6f GSEventRunModal + 161 22 UIKit 0x000000010d4d4c68 UIApplicationMain + 159 23 Favorite Websites 0x000000010c516e0f main + 111 24 libdyld.dylib 0x00000001107af68d start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

这是错误来源的 MasterViewController.swift 代码。

class MasterViewController: UITableViewController, ModelDelegate {

    var detailViewController: DetailViewController? = nil


    var model: Model! = nil // manages the app's data

    // conform to ModelDelegate protocol; updates view wehn model changes
    func modelDataChanged(){
        tableView.reloadData() // reload the UITableView
    }

    // called after the view loads for further UI configuration
    override func viewDidLoad() {
        super.viewDidLoad()

        // set up left and right UIBarButtonItems
        self.navigationItem.leftBarButtonItem = self.editButtonItem

        let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: Selector(("addButtonPressed:")))
        self.navigationItem.rightBarButtonItem = addButton

        if let split = self.splitViewController {
            let controllers = split.viewControllers
            self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
        }

        model = Model(delegate: self) // create the Model
        model.synchronize() // tell model to sync its data

    }

    // displays a UIAlertController to obtain new url from user

    func addButtonPressed(sender: AnyObject) {
        displayAddEditurlSearchAlert(isNew: true, index: nil)
    }

    // handles long press for editing or sharing a url
    func tableViewCellLongPressed(
        sender: UILongPressGestureRecognizer){
        if sender.state == UIGestureRecognizerState.began &&
            !tableView.isEditing {
            let cell = sender.view as! UITableViewCell // get cell

            if let indexPath = tableView.indexPath(for: cell) {
                displayLongPressOptions(row: indexPath.row)
            }
        }
    }

    // displays the edit/share options
    func displayLongPressOptions(row: Int){
        // create UIAlertController for user input
        let alertController = UIAlertController(title: "Options",
                                                message: "Edit or Share your url",
                                                preferredStyle: UIAlertControllerStyle.alert)

        // create Cancel action
        let cancelAction = UIAlertAction(title: "Cancel",
                                         style: UIAlertActionStyle.cancel, handler: nil)
        alertController.addAction(cancelAction)

        let editAction = UIAlertAction(title: "Edit",
                                       style: UIAlertActionStyle.default,
                                       handler: {(action) in
                                        self.displayAddEditurlSearchAlert(isNew: false, index: row)})
        alertController.addAction(editAction)

        let shareAction = UIAlertAction(title: "Share",
                                        style: UIAlertActionStyle.default,
                                        handler: {(action) in self.shareurlSearch(index: row)})
        alertController.addAction(shareAction)
        present(alertController, animated: true,
                              completion: nil)
    }

    // displays add/edit dialog
    func displayAddEditurlSearchAlert(isNew: Bool, index: Int?){
        // create UIAlertController for user input
        let alertController = UIAlertController(
            title: isNew ? "Add URL" : "Edit URL",
            message: isNew ? "" : "Modify your URL",
            preferredStyle: UIAlertControllerStyle.alert)

        // create UITextFields in which user can enter a new URL
        alertController.addTextField(
            configurationHandler: {(textField) in
                if isNew {
                    textField.placeholder = "Enter URL"
                }else{
                    textField.text = self.model.queryForTagAtIndex(index: index!)
                }
        })

        alertController.addTextField(
            configurationHandler: {(textField) in
                if isNew {
                    textField.placeholder = "Tag your URL"
                }else {
                    textField.text = self.model.tagAtIndex(index: index!)
                    textField.isEnabled = false
                    textField.textColor = UIColor.lightGray
                }
        })

        // create Cancel action
        let cancelAction = UIAlertAction(title: "Cancel",
                                         style: UIAlertActionStyle.cancel, handler: nil)
        alertController.addAction(cancelAction)

        let saveAction = UIAlertAction(title: "Save",
                                       style: UIAlertActionStyle.default,
                                       handler: {(action) in
                                        let query =
                                            ((alertController.textFields?[0])! as UITextField).text
                                        let tag =
                                            ((alertController.textFields?[1])! as UITextField).text

                                        // ensure query and tag are not empty
                                        if !query!.isEmpty && !tag!.isEmpty {
                                            self.model.saveQuery(
                                                query: query!, forTag: tag!, syncToCloud: true)

                                            if isNew {
                                                let indexPath =
                                                IndexPath(row: 0, section: 0)
                                                self.tableView.insertRows(at: [indexPath],
                                                                          with: .automatic)
                                            }
                                        }
        })
        alertController.addAction(saveAction)

        present(alertController, animated: true,
                              completion: nil)

    }

    // displays share sheet
    func shareurlSearch(index: Int) {
        let message = "Check out this cool Web site"
        let urlString = urlEncodeString(string: model.queryForTagAtIndex(index: index)!)
        let itemsToShare = [message, urlString]

        // create UIActivityViewController so user can share url
        let activityViewController = UIActivityViewController(
            activityItems: itemsToShare, applicationActivities: nil)
        present(activityViewController,
                              animated: true, completion: nil)
    }

        // MARK: - Segues


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showDetail" {
            if let indexPath = self.tableView.indexPathForSelectedRow {

                let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController

                // get query String
                let query = String(model.queryForTagAtIndex(index: indexPath.row)!)

                // create NSURL to perfrom url search

                controller.detailItem = NSURL(string: urlEncodeString(string: query!))
                controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem
                controller.navigationItem.leftItemsSupplementBackButton = true
            }
        }
    }

    // returns a URL encoded version of the query String
    func urlEncodeString(string: String) -> String {
        return string.addingPercentEncoding(
            withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!
    }

    // MARK: - Table View
    // callback that returns total number of sections in UITableView
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    // callback that returns number of rows in the UITableView
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return model.count
    }

    // callback that returns a configured cell for the given NSIndexPath
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        // get cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as UITableViewCell

        // set up long press guesture recognier
        cell.textLabel!.text = model.tagAtIndex(index: indexPath.row)

        // set up long press guesture recognizer
        let longPressGestureRecognizer = UILongPressGestureRecognizer(
            target: self, action: Selector(("tableViewCellLongPressed:")))
        longPressGestureRecognizer.minimumPressDuration = 0.5
        cell.addGestureRecognizer(longPressGestureRecognizer)

        return cell
    }

    //callback that return whether a cell is editable
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true // all cells are editable
    }

    // callback that deletes a row from the UITableView
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            model.deleteurlSearchAtIndex(index: indexPath.row)

            // remove UITableView row
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
    }
    // callback that returns whether cells can be moved
    override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
            return true
        }

    // callback that reorders keys when user moves them in the table
    override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath,
                            to destinationIndexPath: IndexPath) {
        // tell model to reorder tags based on UITableView order
        model.moveTagAtIndex(oldIndex: sourceIndexPath.row,
                             toDestinationIndex: destinationIndexPath.row)
    }

}

最佳答案

问题是这个表达式:

Selector(("addButtonPressed:"))

替换为:

#selector(addButtonPressed)

关于ios - 没有构建错误,但在模拟器中崩溃。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42370636/

相关文章:

iphone - 从 UIPicker 中的 plist 字典中对数据进行数字排序

ios - View 隐藏时如何禁用 UISlider 交互?

ios - 如何实现 CoreData 记录的重新排序?

iphone - iOS View subview 无法识别自定义类成员

iphone - 使用其他应用程序打开 pdf

ios - 在XCode 7.1上滚动UICollectionView时的模拟器滞后

swift - 如何从 MacOS 上的 SwiftUI 中的 TextField 移除焦点?

swift - 如何在 Realm 移动平台中管理 session ?

ios - 2017/Swift 3.1 - GCD 与 NSOperation

xcode - 组件模拟器列表为空 Xcode 9.1 beta