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

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

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

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

Q&A

解決済

1回答

2868閲覧

SwiftのUserDefaultsのクラスとメソッドの使い方につきまして

pegy

総合スコア245

Swift

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

0グッド

1クリップ

投稿2020/04/05 11:02

編集2020/04/05 12:35

(環境)
xcode:11.3
version 5.1.3

(参考文献)
「たった2日でマスターできるIPhoneアプリ開発集中講座 Xcode 11 Swift5 対応」
2020年1月20日 初版第二刷発行
著者: 藤 治仁・小林 加奈子・小林 由憲
発行人: 片柳 秀夫
編集人:三浦 聡
発行所:ソシム株式会社

基本的にswiftでの調べ方についてご質問させてください。

上記の書籍に基づき、例えば、下記のviewController.swiftにおいて初めてデータの永続化をuserDefaultsクラスを利用することができることを学びました。standardクラスのregister()メソッドので永続化したいデータを登録してinteger()メソッドで数値列として登録した永続データの値を取り出すことができるのか。。ふむふむ。というのが思考過程です。

swift

1//viewController.swift 2 3 override func viewDidLoad() { 4 super.viewDidLoad() 5 // Do any additional setup after loading the view. 6 7 // UserDefaultsのインスタンスを生成 8 let settings = UserDefaults.standard 9 // UserDefaultsに初期値を登録 10 settings.register(defaults: [settingKey:10]) 11 } 12//中略 13 14 // UserDefaultsのインスタンスを生成 15 let settings = UserDefaults.standard 16 // 取得した秒数をtimerValueに渡す 17 let timerValue = settings.integer(forKey: settingKey) 18

また、UserDefaultsのDefinitionを見る限り、それぞれのクラスやメソッドについて、以下の様な記載が確認できました。

Definition

1 2 /** 3 +standardUserDefaults returns a global instance of NSUserDefaults configured to search the current application's search list. 4 */ 5 open class var standard: UserDefaults { get } 6 /** 7 -registerDefaults: adds the registrationDictionary to the last item in every search list. This means that after NSUserDefaults has looked for a value in every other valid location, it will look in registered defaults, making them useful as a "fallback" value. Registered defaults are never stored between runs of an application, and are visible only to the application that registers them. 8 9 Default values from Defaults Configuration Files will automatically be registered. 10 */ 11 12 13 /** 14 -integerForKey: is equivalent to -objectForKey:, except that it converts the returned value to an NSInteger. If the value is an NSNumber, the result of -integerValue will be returned. If the value is an NSString, it will be converted to NSInteger if possible. If the value is a boolean, it will be converted to either 1 for YES or 0 for NO. If the value is absent or can't be converted to an integer, 0 will be returned. 15 */ 16 open func integer(forKey defaultName: String) -> Int

一方で、UiPickerでユーザーが選択した数値列の値を改めて格納するコードで示されているのが下記の通りなのですが、上記から当然standardクラスのregister()メソッドを使うのかと思いきや、setValue()メソッドが使用されており、setValueUserDefaultsクラスに特に言及がなく手詰りという結果になってしまいました。つまり、どの様な場合にはregister()メソッドでどの様な場合にはsetValue()メソッドが識別することができないという状況です。

swift

1//SettingViewController.swift 2 3 func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 4 // UserDefaultsの設定 5 let settings = UserDefaults.standard 6 settings.setValue(settingArray[row], forKey: settingKey) 7 settings.synchronize() 8 }

基本的な調べ方のアプローチをお尋ねしたいのですが、
① Definitionの構造は例えばUserDefaults で俯瞰してみると以下の様になっていました。この記載はつまり両クラスがどの様な関係にあることを言いたいのでしょうか。この点からdefinitionからは理解することができませんでした。特に{get}の意味するところが不明でした。

Definition

1open class UserDefaults : NSObject { 2 /** 3 +standardUserDefaults returns a global instance of NSUserDefaults configured to search the current application's search list. 4 */ 5 open class var standard: UserDefaults { get } 6}

②また、①の状況だからこそなのですが、 下記の様なdefitionであるとUserDefaultsのメソッドとしてregister()がある様に見えてしまいます。実際にはUserDefaults.standard.register()なのでstandardクラスとregister()が並列な関係の様に見えて不思議です。ここら辺のDefinitionの見方を特に知りたいです。

Definition

1open class UserDefaults : NSObject { 2 open class var standard: UserDefaults { get } 3 open func register(defaults registrationDictionary: [String : Any]) 4}

③最後に唯一具体的なことになってしまうのですが、なぜsetValue()UserDefaultsクラスの説明の中に出てこないのでしょうか、、①②がわかれば自ずとわかるかもしれませんが。

また、ここら辺の定義やマニュアルの調べ方についてSwiftでわかりやすい解説サイトとかがあればそれをご教示いただくだけでもとても助かります。

長文で申し訳ございませんが
よろしくお願い申し上げます。

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

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

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

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

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

TsukubaDepot

2020/04/05 12:22

質問内容が「Swiftの基本的なDefinitionの調べ方」というよりも、UserDefaultsのメソッド、およびシングルトンと呼ばれている手法のことに関する内容なので(おそらく...)、タイトルを変更された方がいいかもしれません。
pegy

2020/04/05 12:34

コメント有難うございます。 シングルトンについては、今見始めており、詳細はわかりませんが、タイトルについては承知を致しました。修正致します。
guest

回答1

0

ベストアンサー

質問の意図を私が理解できているかわかりませんが、


UserDefaultsというのは、なんとなく「データを永続化してくれるクラス」という理解で良いと思いますが、
実は
・アプリ単体で使う場合
・複数のアプリ間で共有する場合
の2パターン(もっとある?)が存在します。

前者で取り扱う場合は、とりあえずUserDefaults.standardを使うんだな程度の認識でいいです。

{ get }は「プロパティかつ取得のみできる(setはできない)」事が定義されている
ぐらいの認識でとりあえずはいいです。


UserDefaultsはクラス、
registerはUserDefaultsクラスのメンバー関数です。
通常のメンバー関数はクラスのインスタンス経由で呼び出す必要があります。

インスタンスという言葉は今後もちょいちょい出てくるので覚えておいた方が良いですが、
「クラス」がプラモデルの設計図だとしたら、「インスタンス」はその設計図から作成された実際のプラモデルそのものを指します。

要は設計図だけではなんもできないので(※下記のとおり例外あり)、そこから作成されたオブジェクトを用いてメンバ関数などにアクセスする必要があります。

じゃあ「UserDefaults.standard」はなんなのよ?となりますが、
これはクラスプロパティ(※用語の自信無し)と呼ばれているもので、
インスタンスが無くても実行できるようになっているものです。
(通常の変数はvarですが、クラス変数はclass varになっています。)
設計図だけで直接アクセスできるプロパティととらえてもらえればいいです。

まとめると
UserDefaultsはクラス、
UserDefaults.standardはクラスプロパティを使ってUserDefaultsのインスタンスを取得(実装がどうなってるか知りませんが、シングルトン的なやつです)
UserDefaults.standard.register(...)でようやく、そのインスタンス経由でメンバ関数が呼べる感じです。


基本的に困ったら一次ソースを見ましょう。
https://developer.apple.com/documentation/foundation/userdefaults
set系はSwiftではset(_:forKey:)のような構文になっています。

解説サイトはあったかなあ・・・。
適当にググって補完してもらうのがよいかなとは思います。

投稿2020/04/06 01:53

編集2020/04/06 02:02
takabosoft

総合スコア8356

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

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

pegy

2020/04/06 11:26

takabosoft様 ありがとうございます、まだまだ初心者なので逆に専門的な細かい知識というよりも、まずはイメージというところでご案内いただいたことがとても助かります。重要なとっかかりになりました! ②について、いろいろな記事や参考書でもピントこなかったことが多かったのですが、「インスタンス」を直接生成せずに、クラスプロパティを経由してメンバ関数に直接アクセスできるという構造のご説明が直感的に非常に分かり易かったです。 なんとなく"そこから作成されたオブジェクトを用いてメンバ関数などにアクセス"というご説明で気になった点があります。少なくともSwiftの世界では設計図であるクラスから生み出される実態は「インスタンス」と捉えているので、これをたまに「オブジェクト」と言い換える場合もあると捉えていますが、厳密な表現で使い分けていらっしゃれば申し訳ございません。 最後の③について、 "set系はSwiftではset(_:forKey:)のような構文になっています。"というご説明とsetValueの関係についてイメージがわかなかったのですが、少し調べたところsetValue は NSUserDefaults のメソッドではなく、親クラスのNSObjectのメソッドである旨の記事を見つけることができました。 おそらくNSUserDefaults クラスはNsObjectlくらすを承継している(ほとんど全てのクラスがその様な関係にあると今は理解していますが)、NSUserDefaults.standard.setValue的な使い方ができるし、NSUserDefaultクラス内のDefiniationを探してもそのメソッドの説明を見つけることができなかったと理解いたしました。 慣れるまでは一次ソースでメソッドなどを見つけることができばければ、ググって他の親クラスのメソッドではないかなど、当たりをつけていこうと思います。 ご協力をいただき、ありがとうございました! 大きな感謝を申し上げます。
takabosoft

2020/04/07 07:07

オブジェクトという言葉はたぶん言語などによって意味が変わってきそうなので、すみませんが私の方でしっかりとした説明はできそうにありません(teratailの過去の質問にもいくつかありましたので興味があれば検索してみは)。 私の回答内の「オブジェクト」は「インスタンス」に置き換えて読んでもらって差し支え有りません。 ③のsetの件ですが、ちょっと私も方で勘違いがありました。 setValueはおかしいですね。 もし書籍がsetValue(_:forKey:)を使っているのであれば、書籍側のミスの可能性がありますので、正誤表などありましたら、確認してみてください。 Swiftにおいては、UserDefaultsへデータを保存するのはset(_:forKey:)系を使います。 ついでにいうと、 settings.synchronize() のsynchronize()関数は現在は使用しないでくださいというお達しが出ています。 参考: https://developer.apple.com/documentation/foundation/userdefaults/1414005-synchronize > this method is unnecessary and shouldn't be used.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問