20717


<https://akira-watson.com/iphone/tableview_3.html>

上記のサイトにあるコードを写経しているのですが、実行すると

[code]

    let subVC: SubViewController = (segue.destinationViewController as? SubViewController)!
    
[/code]

の部分が SIGABRTと表示されます。

SIGABRTとはコードを入力する順番が違う、某サイトで見たのですが、今回もそういうことなのでしょうか。。。

[code]

    import UIKit
    
    class ViewController: UIViewController , UITableViewDataSource, UITableViewDelegate{
    
        @IBOutlet var table:UITableView!
    
        let imgArray: NSArray = ["img0.png", "img1.png", "img2.png", "img3.png"]
    
        let label2Array: NSArray = ["あ", "い", "え", "う"]
    
        var selectedImage: UIImage?
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return imgArray.count
        }
    
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
            let cell = table.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath)
    
            let img = UIImage(named: "\(imgArray[indexPath.row])")
    
            let imageView = table.viewWithTag(1) as! UIImageView
            imageView.image = img
    
            let label1 = table.viewWithTag(2) as! UILabel
            label1.text = "No.\(indexPath.row + 1)"
    
            let label2 = table.viewWithTag(3) as! UILabel
            label2.text = "\(label2Array[indexPath.row])"
    
            return cell
    
                }
    
        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    
            selectedImage = UIImage(named:"\(imgArray[indexPath.row])")
            if selectedImage != nil {
    
            performSegueWithIdentifier("toSubViewController", sender: nil)
        }
    
        }
    
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
            if (segue.identifier == "toSubViewController") {
                let subVC: SubViewController = (segue.destinationViewController as? SubViewController)!
                subVC.selectedImg = selectedImage
    
            }
        }
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
    }
    
[/code]


CC BY-SA 3.0
2016-01-07T11:28:24.157
20714
2016-01-08T10:20:39.500
2016-01-07T11:55:06.593
8000
13833
question
swift
SIGABRTと表示される


Table View Cell の Attributes inspector で Identifier に 「tableCell」と指定出来ていますか？


CC BY-SA 3.0
2016-01-07T12:16:42.210
20715
2016-01-07T12:16:42.210
8044
20714
answer


「SIGABRT」は、多種の原因で出るエラーメッセージで、とくに「コードを入力する順番が違う」ことに特定できるものではありません。

プログラムコードの「写経」は、コードの一行一行、ひとつの語句それぞれがどういう意味を持っているのか、意識しながら行わないと、意味のない行為に陥ります。

[code]

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
        let cell = table.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath) // table→tableView
    
        let img = UIImage(named: "\(imgArray[indexPath.row])")
    
        let imageView = table.viewWithTag(1) as! UIImageView
        imageView.image = img // table→tableView
    
        let label1 = table.viewWithTag(2) as! UILabel // table→tableView
        label1.text = "No.\(indexPath.row + 1)"
    
        let label2 = table.viewWithTag(3) as! UILabel // table→tableView
        label2.text = "\(label2Array[indexPath.row])"
    
        return cell
    
            }
    
[/code]

ここがいい例ですが、メソッドの引数`tableView`と、メソッドの実装内で使われている変数`table`が一致していないことに気づかず「写経」していては、仏様はけっして降臨してきません。

エラーの原因の箇所だけでなく、全体を見直して書き直してみました。

[code]

    import UIKit
    
    class ViewController: UIViewController , UITableViewDataSource, UITableViewDelegate{
    
        // Storyboardで定義したオブジェクトには、weak属性を付ける。
        @IBOutlet weak var table:UITableView!
    
        // NSArray型にキャストする意味はありません。逆にSwiftの配列のままであれば、要素をいちいちダウンキャスト（as? String）しなくてすむ。
        let imgArray: [String] = ["img0.png", "img1.png", "img2.png", "img3.png"]
        // 同様に、NSArrayにキャストしない。
        let label2Array: [String] = ["あ", "い", "え", "う"]
    
        var selectedImage: UIImage?
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return imgArray.count
        }
    
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
            let cell = tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath)
    
            // NSArrayのキャストをやめたおかげで、すっきりシンプルなコードになりました。
            let img = UIImage(named: imgArray[indexPath.row])
    
            let imageView = tableView.viewWithTag(1) as! UIImageView
            imageView.image = img
    
            let label1 = table.viewWithTag(2) as! UILabel
            label1.text = "No.\(indexPath.row + 1)"
    
            let label2 = table.viewWithTag(3) as! UILabel
            // これもすっきりシンプル。
            label2.text = label2Array[indexPath.row]
    
            return cell
        }
    
        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    
            // これもすっきりシンプルで。
            // Optional Binding構文を使う。
            if let image = UIImage(named: imgArray[indexPath.row]) {
                selectedImage = image 
                performSegueWithIdentifier("toSubViewController", sender: nil)
            }
        }
    
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
            if (segue.identifier == "toSubViewController") {
                // Optional Binding構文を使う。
                if let subVC = segue.destinationViewController as? SubViewController {
                    subVC.selectedImg = selectedImage
                }
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    
    }
    
[/code]

これでまだエラーが出るようでしたら、コメント欄にコメントください。


CC BY-SA 3.0
2016-01-07T12:43:16.417
20717
2016-01-07T22:38:58.093
2016-01-07T22:38:58.093
7362
7362
20714
answer


質問に書いてある参考にしているサイトの『1. 画面遷移先の View Controller
を新しく作成』の部分に以下のような記述がありますが、この部分はちゃんと設定されているでしょうか？

> ストーリーボードで 新しく作った View Controller を選択して  
>  ライブラリーエリアの Identity Inspector に入り  
>  「Custom Class」の「Class」から、候補が選択できます
>
> SubViewController を選択

実行時のSIGABRTは、segue.destinationViewControllerをSubViewControllerにキャストしようとして失敗したのが原因のように思われます。


CC BY-SA 3.0
2016-01-08T10:20:39.500
20749
2016-01-08T10:20:39.500
7459
20714
answer