🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Swift

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

Q&A

解決済

2回答

1386閲覧

SWIFTにてclass内で呼び出したstatic変数の値が保存されない

masayoshi555

総合スコア9

Swift

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

0グッド

0クリップ

投稿2019/12/22 20:58

編集2019/12/23 21:16

困りごと

以下のコードの最初に宣言しているstatic変数6つ(A〜F)のうち、必ず3つ目の値が欠如する問題が起きており困っています。
3つ毎ではなく、3つ目のみです。

2019/12/24追記
現象はコード内最後に記述されている、PostNewRequest関数内のqueryParameters内で使う際に起きます。
■現象イメージ
以下の場合、Cに値渡しされない。

queryParameters = [ "sample" : [ [ "keyA": A, "keyB": B, "keyC": C], [ "keyA": A, "keyD": D, "keyE": E], [ "keyA": A, "keyB": F] ] ]

以下の場合、Aに値渡しされない。

queryParameters = [ "sample" : [ [ "keyA": A, "keyB": F], [ "keyA": A, "keyB": B, "keyC": C], <-ここ [ "keyA": A, "keyD": D, "keyE": E] ] ]

###やったこと
変数viewzDidLoadにて初期値を入れましたが、3つ目だけ初期値も入りません。
また、変数の順番も関係なく、変数の記述順を変えても必ず3つ目のみ値が入りません。(その他はちゃんと入る)
計算式でforced unwrapをしているのが悪さをしているのかと思いましたが、sliderを使わなかった場合も同様の現象が起きます。

現象確認方法

sendRequest関数にBrakePointを設定し、関数実行を途中で止めました。
その上でqueryParameters内の該当する変数の値を確認しています。

インターフェイス外観

![イメージ説明

swift

1import UIKit 2import Foundation 3import SwiftyJSON 4import CryptoSwift 5 6class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { 7 static var A: String = "" 8 static var B: String = "" 9 static var C: String = "" 10 static var D: String = "" 11 static var E: String = "" 12 static var F: String = "" 13 14 override func viewDidLoad() { 15 super.viewDidLoad() 16//現象確認用にここで初期値を宣言してもqueryParameters内の3つ目の値が入らない 17 ViewController.A = "文字列" 18 ViewController.B = "1000" 19 ViewController.C = "2000" 20 ViewController.D = "1900" 21 ViewController.E = "900" 22 ViewController.F = "950" 23 } 24//以下でスライダーで調整した値と「highMaximum」「lowMaximum」で入力した値をかけて元の値に足す 25//以下の.floor(nearest:0.5)はFloatにextensionをつけて数字の丸め方を変えています 26 @IBOutlet weak var inputA: UITextField! 27 @IBOutlet weak var highMaximum: UITextField! 28 @IBOutlet weak var lowMaximum: UITextField! 29 @IBOutlet weak var highNum: UILabel! 30 @IBAction func highRangeSelector(_ sender: UISlider) {//Sliderは0〜1 31 let highNumCalc = Float(inputA.text!)! + Float(highMaximum.text!)! * sender.value 32 highNum.text = String(highNumCalc.floor(nearest:0.5)) 33 ViewController.C = String(highNumCalc.floor(nearest:0.5)) 34 let highForD = highNumCalc - 100 35 ViewController.D = String(highForD.floor(nearest: 0.5)) 36 ViewController.B = inputA.text!//念押しでsliderを調整する毎にBに値を入れておく 37 } 38 @IBOutlet weak var lowNum: UILabel! 39 @IBAction func lowRangeSelector(_ sender: UISlider) {//Sliederは-1〜0 40 let lowNumCalc = Float(inputA.text!)! + Float(lowMaximum.text!)! * sender.value 41 lowNum.text = String(lowNumCalc.floor(nearest:0.5)) 42 ViewController.E = String(lowNumCalc.floor(nearest:0.5)) 43 let lowForF = lowNumCalc + 50 44 ViewController.F = String(lowForF.floor(nearest: 0.5)) 45 ViewController.B = inputA.text!//念押しでsliderを調整する毎にBに値を入れておく 46 } 47//このボタンが押されると、PostNewRequestクラス内の変数でbuildURLRequestが実行される 48 @IBOutlet weak var sendButton: UIButton! 49 @IBAction func sendRequest(_ sender: Any) { 50 let post = PostNewRequest() 51// (省略) 52 } 53 54// To post 55 final class PostNewRequest { 56// (省略) 57 static var queryParameters: [String: Any] = [ここでstatic変数を使いたい] 58// (省略) 59 func buildURLRequest() {} 60 init() {} 61 } 62} 63

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2019/12/23 21:14

"がおかしなことになってますが、転載する際のタイポとして扱っていいのでしょうか? すでに実行されているでしょうが… 値が入っていないということでしたら、例えば、final class PostNewsRequest { の1行うえに print("A: \(A)") print("C: \(C)")とでも書いて実行すれば、問題の切り分けができると思います。
masayoshi555

2019/12/23 21:17

ご指摘の転載上のタイポは修正いたしました。ありがとうございます。 また、検証方法のご提案ありがとうございます。 また後ほど検証結果を記載したいと思います。
guest

回答2

0

自己解決

takabosoftさんご指摘のstaticの件もポイントでしたが、もう一つ要因がありました。

これ以外にtextfieldが2つあり、計3つのtextfieldを持っています。
検証の際、textfieldへ入力し、最後のtextfieldへ入力後そのままボタン(sendButton)を押すと、textfieldの値が反映されず、sendRequest関数が実行されることでした。

なので、sendButton押下でsendRequest関数実行時、以下のコードを挟むことで解決出来ました。

swift

1@IBAction func sendRequest(_ sender: Any) { 2 inputA.endEditing(true) 3 highMaximum.endEditing(true) 4 lowMaximum.endEditing(true) 5 let post = PostNewRequest() 6// (省略) 7 }

問題の一端及びそもそもの構成の指摘をして頂いたtakabosoftさんありがとうございました。
tyobigorouさんもありがとうございました。

投稿2019/12/24 19:02

編集2019/12/24 19:04
masayoshi555

総合スコア9

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

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

0

検証をしていないので適当な事を書きますが、
静的変数の初期化値に静的変数を使うことは、
静的変数の初期化順の影響を受けるので、避けたほうがよいと思います。

おそらくstaticをすべて辞めれば解決する話だとは思います。
今回載せてもらった箇所で静的変数の必要性は感じません。

投稿2019/12/23 00:34

takabosoft

総合スコア8356

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

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

masayoshi555

2019/12/23 19:10 編集

@takabosoft さん回答ありがとうございます。 >静的変数の初期化値に静的変数を使うことは、静的変数の初期化順の影響を受けるので、避けたほうがよいと思います。 勉強不足でした。その点自分なりに調べてみます。 ご指摘の部分、実はエラーが出るからstaticにしていました。(上記のようなことは知らなかったです) staticを外すと以下のエラーになります。 「Instance member '(AからF)' of type 'ViewController' cannot be used on instance of nested type 'ViewController.PostNewRequest'」 class内にclassを作っている上に、queryParametersもnestedになっております。 (queryParametersは関係ない?) queryParameters = [ "sample" : [ [ "keyA": A, "keyB": B, keyC": C], [ "keyA": A, "keyD": D, keyE": E], [ "keyA": A, "keyB": F] ] ] staticだと解決出来たので安易にしていました。 ちなみに解決方法として、override func viewDidLoad() 内の初期の宣言をやめつつ、変数をViewControllerの外に出してグローバル変数にするというのはわかるのですが、メモリの消費を気にしていました。(実際はどうなのか理解していませんが) もしグローバル変数以外の解決方法ご存知でしたら教えて頂けると幸いです。
masayoshi555

2019/12/23 19:59 編集

続報:上記に基づき、以下のコードにて実施したところ、「3つ目の変数が入らない。」現象は引き続き出てしまいました。 import ... var A: String = "" var B: String = "" var C: String = "" var D: String = "" var E: String = "" var F: String = "" class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {     (staticは削除) override func viewDidLoad() { super.viewDidLoad()       (staticは削除) } 現象イメージを質問欄に追記しました。
takabosoft

2019/12/24 00:16

AからFをグローバル変数にする必要もありません。というかグローバル変数もstatic変数も似たようなものなので、出来る限り利用を避けてください。 queryParametersもstaticである必要は全く無く、必要な時に動的に作成するべきです。 でないと二度目以降で変数が更新されないという不具合がついてくるはずです。
masayoshi555

2019/12/24 18:51

takabosoftさん たくさんのご指摘ありがとうございます。 ご指摘の通り、queryParametersをstaticにしていると2回目以降変数が反映されませんでした。 変数のスコープについては勉強しなおします。(static外し構成作り替えた結果しっかりと反映されました)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問