質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

2回答

319閲覧

Thread 1: signal SIGABRT

hahum

総合スコア65

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/01/05 04:12

編集2022/01/12 10:55

追記 1/9

himeji001さんのアドバイス通りやってみたところ
Array1には回数の入ったresultArray1と日付が入ったdateArray1を入れることが出来ました。

しかしSaveViewControllerのViewDidLoadで,取り出しArray2に代入して、cellForRowAtにresultArray2とdateArray2のIndexPath.rowを表示させることがまだ出来ません。(Thread 1: Fatal error: Index out of range)
そもそも、Array2 = [resultArray2, dateArray2]なのでArray2[IndexPath.row]はわかりますが、その中の配列resultArray2、dateArray2に[IndexPath.row]は使えないですよね。それぞれ新しく更新されたデータをcellForRowAtで
cell.textLabel!.text (resultArray2の値)
cell.detailTextLabel!.text(dateArray2の値)
を入れる方法はありますでしょうか。
あと、ViewWillAppearはreloaddataだけでいいのか教えていただきたいです。

そしてスッキリした分かりやすいコードを書くために些細なことでもいいのでアドバイスいただけたら幸いです。

ResultViewController.swift

Swift

1 2var resultArray1 = [String]() 3 4 var dateArray1 = [String]() 5 6 var Array1: [[String]] = [] 7 8 var date = Date() 9 10 11... 12... 13... 14 15@IBAction func record(_ sender: Any) { 16 17 //配列を取り出す 18 if (UserDefaults.standard.object(forKey: "save") != nil) { 19 Array1 = UserDefaults.standard.object(forKey: "save") as! [[String]] 20 21 } 22 23 24 //zikanを呼び出す 25 zikan() 26 //resultArrayに回数を追加 27 resultArray1.append(countLabel2.text!) 28 29 Array1 = [resultArray1, dateArray1] 30 31 UserDefaults.standard.set(Array1, forKey: "save") 32 33 print(Array1.description) 34 print(resultArray1.description) 35 print(dateArray1.description) 36 } 37 38 39 func zikan() { 40 //日付のフォーマットを指定する 41 let format = DateFormatter() 42 format.dateFormat = DateFormatter.dateFormat(fromTemplate: "yMdkHm", options: 0, locale: Locale(identifier: "ja_JP")) 43 44 //日付をStringに変換する 45 let sDate = format.string(from: date) 46 //日付をdateArrayに入れる 47 dateArray1.append(sDate) 48 }

SaveViewController.swift

swift

1var resultArray2 = [String]() 2 3 var dateArray2 = [String]() 4 5 var Array2: [[String]] = [] 6 7... 8... 9... 10 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 15 tableView.delegate = self 16 tableView.dataSource = self 17 18 //Array2にresultArray2とdateArray2を代入 19 Array2 = [resultArray2, dateArray2] 20 21 if UserDefaults.standard.object(forKey: "save") != nil { 22 23 Array2 = UserDefaults.standard.object(forKey: "save") as! [[String]] 24 } 25 26 print(resultArray2.description) 27 print(dateArray2.description) 28 print("Array2:", Array2.description) 29 30 31 } 32 33 34 override func viewWillAppear(_ animated: Bool) { 35 super.viewDidAppear(animated) 36 37 38 39 tableView.reloadData() 40 41 42 } 43 44 45 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 46 return Array2.count 47 } 48 49 func numberOfSections(in tableView: UITableView) -> Int { 50 return 1 51 } 52 53 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 54 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 55 56 cell.textLabel!.text = resultArray2[indexPath.row] 57 cell.detailTextLabel!.text = dateArray2[indexPath.row] 58 59 return cell 60 } 61 62 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 63 return 40 64 } 65 66 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { 67 68 if editingStyle == .delete { 69 Array2.remove(at: indexPath.row) 70 71 UserDefaults.standard.set(Array2, forKey: "save") 72 73 tableView.reloadData() 74 } 75 } 76

・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

追記1/9

Array2 = UserDefaults.standard.object(forKey: "save") as! [[String]]のところにThread 1: signal SIGABRTが発生する理由がわかりません。不必要なキャッシュは切ってあります。

swift

1 2var resultArray2 = [String]() 3 4 var dateArray2 = [String]() 5 6 var Array2: [[String]] = [] 7 8 9... 10... 11... 12 13 14 15override func viewDidLoad() { 16 super.viewDidLoad() 17 18 tableView.delegate = self 19 tableView.dataSource = self 20 21 if UserDefaults.standard.object(forKey: "save") != nil { 22 23 Array2 = UserDefaults.standard.object(forKey: "save") as! [[String]] 24 } 25 26 27 self.resultArray2 = self.Array2[0] 28 self.dateArray2 = self.Array2[1] 29 30 Array2 = [resultArray2, dateArray2] 31 32 33 //Array2 = [ ["晴れ", "雨", "雪"], 34 //["2019/1/1", "2019/1/2", "2019/1/3"] ] 35 36 print("Array2:", Array2.description) 37 print(resultArray2.description) 38 print(dateArray2.description) 39 40 } 41 42 43 override func viewWillAppear(_ animated: Bool) { 44 super.viewDidAppear(animated) 45 46 tableView.reloadData() 47 } 48 49 50 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 51 52 return resultArray2.count 53 54 } 55 56 func numberOfSections(in tableView: UITableView) -> Int { 57 return 1 58 } 59 60 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 61 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 62 63 64 print("Array2:at cellForRowAt", Array2.description) 65 print(Array2.count) 66 print(resultArray2.description) 67 print(dateArray2.description) 68 69 cell.textLabel!.text = resultArray2[indexPath.row] 70 cell.detailTextLabel!.text = dateArray2[indexPath.row] 71 72 return cell 73 } 74 75 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 76 return 40 77 } 78 79 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { 80 81 if editingStyle == .delete { 82 Array2.remove(at: indexPath.row) 83 84 UserDefaults.standard.set(Array2, forKey: "save") 85 86 tableView.reloadData() 87 } 88 } 89

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

エラーコードに書かれているとおり、プロパティイニシャライザーの中でresultArray1やresultArray2を使うことができません。

var Array1 = [resultArray1,dateArray1]を
var Array1: [[String]]に変更して、
viewWillAppear()関数の中でArray1 = [resultArray1, dateArray1]を使用してみてはいかがでしょうか。

投稿2019/01/07 05:06

AOKINAO

総合スコア268

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2019/01/07 05:20

なぜviewWillAppear?
AOKINAO

2019/01/07 05:55

SaveViewController.swiftにviewWillAppear()があったのでviewWillAppear()と書いてしまいましたが、viewDidLoad()の方が適切ですね。
hahum

2019/01/07 08:44

ありがとうございます!エラーは出なくなりましたが、実行ボタンを押したときにcellForRowAtのcell.textLabel!.text = resultArray2[indexPath.row]のところにThread 1: Fatal error: Index out of rangeと出ました。範囲外のindexと言う意味ですが、どこが範囲外なのしょうか。
hameji001

2019/01/07 08:52

cellForRowAtの中身として記載しているArrayと numberOfRowsInSectionのArrayの個数をよく考えてみてください。 わからないなら、printでviewdidload内に記載し、個数を取得してみてください。
hahum

2019/01/07 19:49

追記に今の状況を記しました。よろしくお願いします。自分でも模索中です。
hameji001

2019/01/07 23:45 編集

なんか色々変ですよ。 var resultArray2 = [String]() var dateArray2 = [String]() の後に変更を加えなければ、 空の配列のままとなり、0を表示します。 print結果からは何も入ってないってことですね。 となると、Array2に入っているものが何かが気になりますよね。 空の配列を保存している懸念があります。 print("Array2:", Array2.description)を記入して、 中身を確認しましょう。 ①UserDefaults.standard.から読み出していますが、 UserDefaultsには何か保存したのでしょうか??? ②Array2は resultArray2とdateArray2を持っているので、 複雑にしたくなければ、それぞれresultArray2とdateArray2別々に userdefaultsに保存し、読み出せばいいのではないでしょうか? 大したメモリの違いにはならなそうですが。 でも個数の違いに繋がりやすくなってしまうか。。。 ③そして、viewWillAppearのコードは viewDidLoadに入れるべきです。 tableView.reloadData()のみ残せばいいです。 ④tableViewのエラーの方も解決していないですよね。 設定行数(numberofRowsInSection)はArray2.count なので print結果から 2個と、 各行の表示内容(cellForRowAt indexPath)での resultArray2[indexPath.row] の個数が一致しないと データを全部表示できないですよ。 (最悪、設定行数が小さくてもいいけど、、、 逆の設定行数が多く、配列以上の要素の読み出しはエラーになります。) まずは、配列をuserdefaultsからではないく、 見える短いものを用意して作ってみてはどうでしょうか??? ex) resultArray = ["晴れ", "雨", "雪"] dateArray = ["2019/1/1", "2019/1/2", "2019/1/3"] のように。となると Array2 = [ ["晴れ", "雨", "雪"], ["2019/1/1", "2019/1/2", "2019/1/3"] ] それで何をしたいか、きちんと表示できるか、やってみたらいいと思います。 その後に置き換えればいいんです。
hahum

2019/01/08 03:17

print("Array2:", Array2.description)にはArray2: [[], []]が出力されました。 //Array2にresultArray2とdateArray2を代入 Array2 = [resultArray2,dateArray2] しているからだと思います。 4,についてですがex)の通りやってみたところ 晴れ            2019/1/1 雨             2019/1/2  がテーブルビューに出力されました そもそもresultViewControllerでUserDefaultsに保存していたArray1にはresultArray1とdateArray1が入っていて、resultArray1には回数(前のViewControllerから受け取った)、dateArray1には日付が入っていたはずで、それをArray2に入れて使おうと思っていたのですが私のやり方がそもそも間違っていたと言うことですよね。
hameji001

2019/01/08 04:03 編集

Array2が空の配列を保存しているという時点で、 そもそものデータの登録がきちんとできていないですね。 Userdefaultsに登録するところを見直してみる必要がありそうです。
hahum

2019/01/08 07:01

print()で確認したところresultArray1とdateArray1には値が入っていましたがArray1には何も入っていませんでした。その何も入っていないArray1を保存していたのでエラーが発生していたものと思われます。viewdidloadで Array1 = [resultArray1, dateArray1] をしたはずなのに、何も入っていないのはおかしいですね。色々試してみます。
hameji001

2019/01/08 09:31

コードが含まれるので、回答を編集しました。 見てみてください。 これで改善すると思います。
guest

0

ざっと見、間違いがあります。

Array1 = UserDefaults.standard.object(forKey: "save") as! [String]

これ間違ってますよ。

Swift

1var resultArray1 = [String]() 2var dateArray1 = [String]() 3 4var Array1 = [resultArray1,dateArray1] 5

とあるので、これを紐解くと、
var Array1 = [String, String]ですよね?
つまり、Array1は[String]を1個、2個と持っている。
[String]のArrayということになるので、
正しくは、

Array1 = UserDefaults.standard.object(forKey: "save") as! [[String]]

です。
まずそこから直してみましょう。他のコードも見てみます。

[以下追記 1/8]
///////////////////////////////////_/

保存のところのコードがやはりおかしいです。
最初に見なくて申し訳なかったです。

Swift

1@IBAction func record(_ sender: Any) { 2 //zikan、①dateArray1に日付をString型で追加保存 3 zikan() 4 //配列を取り出す ②もし過去のデータがあるなら、Array1に読み込む 5 if (UserDefaults.standard.object(forKey: "save") != nil) { 6 Array1 = UserDefaults.standard.object(forKey: "save") as! [String] 7 } 8 // ③resultArray1にStringを追加保存 9 resultArray1.append(countLabel2.text!) 10 /*//日付をdateArrayに入れる 11 dateArray1.append(sDate)*/ 12 // ④userdefaultsに再度保存 13 UserDefaults.standard.set(Array1, forKey: "save") 14} 15 16func zikan() { 17 //日付のフォーマットを指定する 18 let format = DateFormatter() 19 format.dateFormat = DateFormatter.dateFormat(fromTemplate: "yMdkHm", options: 0, locale: Locale(identifier: "ja_JP")) 20 //日付をStringに変換する 21 let sDate = format.string(from: date) 22 //日付をdateArrayに入れる 23 dateArray1.append(sDate) 24 } 25

func zikan()に関してはまぁ、置いといて、
@IBOutlet func record() {}に関してですが、
追加記入した、順番と行なっていることを考えてください。
①dateArray1に日付(String型)を追加保存
②もし過去のデータがあるなら、Array1に読み込む
③resultArray1にStringを追加保存
④userdefaultsにArray1を再度保存

データ構造と共に加味すると、

Swift

1var resultArray1 = [String]() 2var dateArray1 = [String]() 3var Array1 = [resultArray1,dateArray1]

resultArray1, dateArray1共に、空配列から始まる
(。。。viewdidLoadで読み込んでたらごめんなさい。)
まず、dateArray1に押した時の日付が保存される。
Array1にUserDefaultsから過去のデータが入る
dateArray1にStringを追加保存する
UserDefaultsにArray1を再度保存している。

の流れ、なので、よく見てもらえると、
Array1は他のdateArray1やresultArray1とやり取りを何もしていません。
これではArray1に何かデータが入るはずがありません。
なので、何も保存されないのです。

正しい流れは、まず、何と言っても

①過去データがあれば読み込む
userdefaults->Array1
②Array1の中身を分解し、追加できるようにセットする
Array1 -> dateArray1とresultArray1に挿入。
③それぞれのdateArray1とresultArray1にデータを追加
④新規データが追加されたdateArray1とresultArray1を再びArray1にセット(戻す)
⑤Array1を永続させるためにUserdefaultsに上書きする
(⑥printでArray1の中身を確認する)

です。
これでArrayにまず初期データがきちんとできると思います。
printで作ったあとは確認してくださいね。

/////////////////////////////////_/
1/9追記

②がないと、過去のデータが読み込まれないので、
その都度、ボタンを押した時に入れた新しいもののみしか保存されません。
なので、永遠に1個しかデータは保存されません。

なので②は

Swift

1self.resultArray1 = self.Array1[0] // Array1の要素0(resultArray1の保存したもの)をresultArray1に入れる 2// Array1つまり、Userdefaultsから保存したものを取り出して、セットした配列ですよ! 3self.dateArray1 = self.Array1[1] // Array1の要素1(dateArray1の保存したもの)をdateArray1に入れる

と書けばいいです。

まだ理解していないみたいですね。
SaveViewController.swiftのviewDidLoad()もおかしいです。
この追記のコードを見て、順番・入る中身をよく考えて、またやってみてください。
func内では基本上から下に順に処理されるんですよ。

理解できれば、なぜprint(resultArray2)とprint(dateArray2)が空なのかわかると思います。

また、エラーは理由が書いてある「Index out of range」ので、
google翻訳でも駆使して、日本語に訳して考えてください。
解決には、以前も書きましたが、

Swift

1func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 2 return Array2.count 3}

で返ってくる個数を考えて、何がおかしいのかを考えてください。
わからなければ、print(Array2.count)で個数の確認もできます。

cellforRowatの取り出し方も、データの構造、
順番・取り出し方等を考えればわかるはずです。

そろそろ同じことを何度もやり取りするのは疲れてきました。
答えは全て、このページに載っています。
よく全体を読んで、理解してください。

投稿2019/01/05 12:34

編集2019/01/09 06:19
hameji001

総合スコア639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hahum

2019/01/09 04:16 編集

//追記1月8日 追記ありがとうございます! ②はコードでいうとどのようになりますか。何度も申し訳ございません。 ②なしでもアドバイス通りこのような順番でやってみると、Array1にresultArray1とdateArray1の値を入れることができました しかし取り出してArray2に入れてみて中身を確認するとArray2には何も入っていません。 コードは再度追記しましたのでご覧いただけたら幸いです。(1/9)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問