Ошибка EXC_BAD_INSTRUCTION при запуске быстрого кода с помощью NSURL

Итак, я создал приложение, которое загружает данные из магазина iTunes для отображения результатов поиска с именем исполнителя, названием песни и названием альбома. Я сделал это с помощью JSON, и приложение отлично работает при первом запуске с панелью поиска, которую я добавил. У меня есть UITextField в навигационной панели с именем searchTerm как @IBOutlet , кнопка – это функция @IBAction которая выводит строку из searchTerm, а затем извлекает данные из iTunes Store. Я загружаю приложение отлично, он успешно работает, и работает первый поиск. Например, если я ищу AC / DC, это загружает: http://imgur.com/mipnLWr . Если я попытаюсь снова выполнить поиск, я получаю следующее: http://imgur.com/hDqrcHm , приложение, замороженное с предыдущими результатами, и эта ошибка в консоли:

 fatal error: unexpectedly found nil while unwrapping an Optional value (lldb) 

и эта ошибка в моем подклассе SongsTableViewController UITableViewController :

 Thread 1: EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP, subcode=0x0) 

Вот мой класс SongsTableViewController:

 import UIKit class SongsTableViewController: UITableViewController { var theSearch = "" @IBOutlet weak var searchTerm: UITextField! @IBAction func search(sender: AnyObject) { theSearch = "\(searchTerm.text)" println("searched") self.fetchData() } var songs = [Song]() private let cache = NSCache() private func fetchData() { let url = NSURL(string: "http://itunes.apple.com/search?term=\(theSearch)&country=us") let session = NSURLSession.sharedSession() let task = session.dataTaskWithURL(url!, completionHandler: { data, response, error in if let taskError = error { //handle error } else { let httpResponse = response as NSHTTPURLResponse switch httpResponse.statusCode { case 200: println("got 200") self.parseJson(data) default: println("request failed: \(httpResponse.statusCode)") } } }) task.resume() } func parseJson(data: NSData) { var error: NSError? let json : AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: &error) if error == nil { if let unwrappedJson: AnyObject = json { parseSongs(json: unwrappedJson) } } } private func parseSongs(#json: AnyObject) { songs = [] if let array = json["results"] as? [[String : AnyObject]] { for songDictionary in array { if let title = songDictionary["trackName"] as? NSString { if let artist = songDictionary["artistName"] as? NSString { if let albumName = songDictionary["collectionName"] as? NSString { if let artworkUrl = songDictionary["artworkUrl100"] as? NSString { let song = Song(title: title, artist: artist, albumName: albumName, artworkUrl: artworkUrl) songs.append(song) } } } } } dispatch_async(dispatch_get_main_queue()) { self.tableView.reloadData() } } } override func viewDidLoad() { super.viewDidLoad() // Uncomment the following line to preserve selection between presentations // self.clearsSelectionOnViewWillAppear = false // Uncomment the following line to display an Edit button in the navigation bar for this view controller. // self.navigationItem.rightBarButtonItem = self.editButtonItem() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: - Table view data source override func numberOfSectionsInTableView(tableView: UITableView) -> Int { // #warning Potentially incomplete method implementation. // Return the number of sections. return 1 } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete method implementation. // Return the number of rows in the section. return songs.count } override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return "\(theSearch) Songs" } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell let song = songs[indexPath.row] cell.textLabel?.text = song.title cell.detailTextLabel?.text = song.albumName if let image = cache.objectForKey(song.artworkUrl) as? UIImage { cell.imageView?.image = image } else { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { let data = NSData(contentsOfURL: NSURL(string: song.artworkUrl)!) let image = UIImage(data: data!) self.cache.setObject(image!, forKey: song.artworkUrl) dispatch_async(dispatch_get_main_queue()) { self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) } } } return cell } /* // Override to support conditional editing of the table view. override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { // Return NO if you do not want the specified item to be editable. return true } */ /* // Override to support editing the table view. override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { if editingStyle == .Delete { // Delete the row from the data source tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) } else if editingStyle == .Insert { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } } */ /* // Override to support rearranging the table view. override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) { } */ /* // Override to support conditional rearranging of the table view. override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool { // Return NO if you do not want the item to be re-orderable. return true } */ // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. let detailViewController = segue.destinationViewController as SongDetailViewController let cell = sender as UITableViewCell let indexPath = tableView.indexPathForCell(cell)! let song = songs[indexPath.row] detailViewController.song = song } } 

и мой SongsDetailViewController :

 import UIKit class SongDetailViewController: UIViewController { var song: Song?; @IBOutlet weak var titleLabel: UILabel! @IBOutlet weak var artistLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() self.updateView(); // Do any additional setup after loading the view. } func updateView() { println("Code Monkey"); titleLabel.text = song?.title artistLabel.text = song?.artist } } 

мой класс песни:

 import Foundation struct Song { var title: String; var artist: String; let albumName: String = ""; let artworkUrl: String = ""; } 

и Main.storyboard как xml:

 <?xml version="1.0" encoding="UTF-8" standalone="no"?> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6254" systemVersion="14A361p" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="J4e-4J-Qag"> <dependencies> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/> </dependencies> <scenes> <!--Songs Table View Controller--> <scene sceneID="o2z-qw-46Z"> <objects> <tableViewController id="7pZ-HZ-fPi" customClass="SongsTableViewController" customModule="Songs" customModuleProvider="target" sceneMemberID="viewController"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="usS-1O-Bb9"> <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <prototypes> <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" textLabel="KyS-jU-iVa" detailTextLabel="v39-NZ-fKp" style="IBUITableViewCellStyleSubtitle" id="Dxe-az-DTs"> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Dxe-az-DTs" id="s0z-IA-UE6"> <autoresizingMask key="autoresizingMask"/> <subviews> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="KyS-jU-iVa"> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <fontDescription key="fontDescription" type="system" pointSize="16"/> <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> <nil key="highlightedColor"/> </label> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Subtitle" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="v39-NZ-fKp"> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <fontDescription key="fontDescription" type="system" pointSize="11"/> <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> <nil key="highlightedColor"/> </label> </subviews> </tableViewCellContentView> <connections> <segue destination="IaK-66-iRk" kind="show" identifier="showSongDetails" id="Qvk-MK-NHw"/> </connections> </tableViewCell> </prototypes> <connections> <outlet property="dataSource" destination="7pZ-HZ-fPi" id="1Fa-g3-eTG"/> <outlet property="delegate" destination="7pZ-HZ-fPi" id="F2P-n2-c00"/> </connections> </tableView> <navigationItem key="navigationItem" id="DSQ-mu-WTl"> <nil key="title"/> <textField key="titleView" opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" minimumFontSize="17" id="OyO-T3-pkK" userLabel="Search"> <rect key="frame" x="180" y="7" width="240" height="30"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <fontDescription key="fontDescription" type="system" pointSize="14"/> <textInputTraits key="textInputTraits"/> </textField> <barButtonItem key="rightBarButtonItem" style="plain" id="fPc-Nn-AF7"> <button key="customView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="hzA-Ku-WOK"> <rect key="frame" x="-23" y="-15" width="133" height="30"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <state key="normal" title="Go"> <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> </state> <connections> <action selector="search:" destination="7pZ-HZ-fPi" eventType="touchUpInside" id="9ny-cc-B47"/> </connections> </button> <connections> <action selector="search" destination="7pZ-HZ-fPi" id="Mav-7f-Nw9"/> </connections> </barButtonItem> </navigationItem> <connections> <outlet property="searchTerm" destination="OyO-T3-pkK" id="LGU-GM-rOh"/> </connections> </tableViewController> <placeholder placeholderIdentifier="IBFirstResponder" id="pBf-2K-Quz" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> <point key="canvasLocation" x="1091" y="421"/> </scene> <!--Song Detail View Controller--> <scene sceneID="EY0-P9-lxp"> <objects> <viewController id="IaK-66-iRk" customClass="SongDetailViewController" customModule="Songs" customModuleProvider="target" sceneMemberID="viewController"> <layoutGuides> <viewControllerLayoutGuide type="top" id="NcC-3p-PzZ"/> <viewControllerLayoutGuide type="bottom" id="v8u-7K-8VY"/> </layoutGuides> <view key="view" contentMode="scaleToFill" id="Gag-Xd-hMv"> <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="neB-pw-mZC"> <rect key="frame" x="115" y="216" width="42" height="21"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> <nil key="highlightedColor"/> </label> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aXT-AM-FSZ"> <rect key="frame" x="115" y="289" width="42" height="21"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> <nil key="highlightedColor"/> </label> </subviews> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <constraints> <constraint firstItem="neB-pw-mZC" firstAttribute="top" secondItem="NcC-3p-PzZ" secondAttribute="bottom" constant="154" id="PwZ-wP-g5X"/> <constraint firstItem="aXT-AM-FSZ" firstAttribute="centerX" secondItem="neB-pw-mZC" secondAttribute="centerX" constant="3" id="SJa-en-Fsl"/> <constraint firstItem="aXT-AM-FSZ" firstAttribute="top" secondItem="neB-pw-mZC" secondAttribute="bottom" constant="50" id="qCi-A1-mRH"/> </constraints> </view> <connections> <outlet property="artistLabel" destination="aXT-AM-FSZ" id="3tP-9I-8KR"/> <outlet property="titleLabel" destination="neB-pw-mZC" id="kBk-Wt-IOE"/> </connections> </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="nNS-Sx-Qsb" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> <point key="canvasLocation" x="1943" y="411"/> </scene> <!--Navigation Controller--> <scene sceneID="d4l-Tj-sHo"> <objects> <navigationController automaticallyAdjustsScrollViewInsets="NO" id="J4e-4J-Qag" sceneMemberID="viewController"> <toolbarItems/> <navigationBar key="navigationBar" contentMode="scaleToFill" id="JSx-T8-Kzc"> <rect key="frame" x="0.0" y="0.0" width="320" height="44"/> <autoresizingMask key="autoresizingMask"/> </navigationBar> <nil name="viewControllers"/> <connections> <segue destination="7pZ-HZ-fPi" kind="relationship" relationship="rootViewController" id="iec-gq-WSz"/> </connections> </navigationController> <placeholder placeholderIdentifier="IBFirstResponder" id="ho4-Dh-fvD" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> <point key="canvasLocation" x="279" y="421"/> </scene> </scenes> </document> 

Я знаю, что разворачивающийся ноль плохой, но почему он разворачивает ноль? SongsTableViewController встречается в строке SongsTableViewController с let task = session.dataTaskWithURL(url!, completionHandler: { , где url – это то, что было развернуто и равно нулю

2 Solutions collect form web for “Ошибка EXC_BAD_INSTRUCTION при запуске быстрого кода с помощью NSURL”

Причина, по которой ваше приложение вылетает при поиске песен с пробелом в имени, связано с тем, что это приводит к неверному URL-адресу. Чтобы создать URL-адрес, вам нужно выполнить правильное экранирование. Если вы этого не NSURL(string: ...) вернет нуль.

Фактически вы не проверяете, действительно ли url (но нет), поэтому ваше приложение падает, как только вы пытаетесь его использовать.

В идеале вы должны действительно использовать NSURLComponents для создания URL-адреса. Он будет принимать базовый URL-адрес, аргументы пути и запроса и кастовать все вместе как действительный экземпляр NSURL , делая все правильное кодирование и экранирование.

Если вы создаете функцию, которая инкапсулирует эту логику, вы можете сделать что-то следующим образом:

 private func fetchData() { if let url = searchURLWithTerm("Foo Fighters") { ... rest of your code here ... } } func searchURLWithTerm(term: String) -> NSURL? { if let components = NSURLComponents(string: "http://itunes.apple.com/search") { components.queryItems = [NSURLQueryItem(name: "country", value: "US"), NSURLQueryItem(name: "term", value: term)] return components.URL } return nil } 

Не использовать

 url! 

вместо этого используйте

 if let url = url { } 

Чтобы убедиться, что это не ноль.

Теперь причина, по которой он не работает, вероятно, меньше с nils и больше с фактическими данными в строке для NSURL. Записывайте его каждый раз, когда он меняется, и пытайтесь использовать его в почтальоне. Если он работает, вы неправильно отправляете запрос. Если он не работает в почтальоне, это плохой URL.

Посмотрите в NSURLConnection, отправьте асинхронный запрос, это значительно усложнит процесс захвата ошибок.

  • Есть ли более эффективный способ удаления локализации из NIB или раскадровки?
  • XCode - локализация iOS не учитывается
  • Включая Google Analytics в Swift Bridging Header
  • Xcode 7 продолжает сбой открытия проекта (xcworkspace)
  • Панель навигации исчезает
  • UITableView устанавливает выбранную строку для обновления управления
  • iOS UITesting: автоматически обрабатывать все системные подсказки с помощью addUIInterruptionMonitorWithDescription
  • OBJ-C: Фиксирование XY-оси Core-Plot
  • Как показать командную строку xcodebuild из xcode?
  • Сделать шоу UIAlertView после второго запуска
  • Почему при первом запуске после установки релиз сборки моего iPhone-приложения падает на устройство?
  • Interesting Posts

    Найти область внутри закрытого объекта в ios

    Как преобразовать значение типа «CBManagerState» в ожидаемый тип «CBCentralManagerState» после преобразования в синтаксис Swift 3.0?

    Отображение названия дорожки и исполнителя для музыки, подкастов и любых приложений

    «Выполнение дорогостоящей бездонной операции!» – что это такое и как его исправить?

    Xcode и iOS9 «Пакеты Asset должны быть в / OnDemandResources»

    Почему в iOS 11 мое UIApplicationState отображается как неактивное состояние вместо активного?

    Передача данных объекта с помощью UIButton press

    NSURLConnection возвращает NSError только на английском языке?

    iOS: постоянно хранить данные аутентификации на устройстве

    MKMapView и viewDidLoad / viewWillAppear / viewDidAppear с использованием раскадровки

    NSTimer не передает аргументы селектору

    Основная сумма данных всех атрибутов экземпляров

    Как использовать автоматическое определение масштаба для всех размеров экрана?

    Интеграция библиотеки .net в приложение Objective C iOS

    iOS: когда завершается создание блока кода фоновой задачи?

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.