teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

5

誤記修正

2017/01/14 03:54

投稿

SatoTakeshiX
SatoTakeshiX

スコア113

answer CHANGED
@@ -90,7 +90,7 @@
90
90
  ではビットフラグを作り、フラグを立てることで変数に複数の状態を表すことができると書かれています。
91
91
  それを今回のSearchPathDomainMask例で提示します。
92
92
 
93
- 突然ですが、今すぐXcodeで新しいプロジェクトを作成して、ViewControllerのviewDidloadで以下のコードを書いてください
93
+ 突然ですが、今すぐXcodeで言語をObjective-Cで新しいプロジェクトを作成して、ViewControllerのviewDidloadで以下のコードを書いてください
94
94
 
95
95
  ```objective-c
96
96
  - (void)viewDidLoad {

4

整理

2017/01/14 03:54

投稿

SatoTakeshiX
SatoTakeshiX

スコア113

answer CHANGED
@@ -63,7 +63,7 @@
63
63
 
64
64
  今Playgroundで確認しました。
65
65
 
66
- ```
66
+ ```swift
67
67
  class A {}
68
68
  extension A {
69
69
  struct StructA {
@@ -108,7 +108,7 @@
108
108
 
109
109
  これを実行するとこんな結果が得られると思います。
110
110
 
111
- ```
111
+ ```Objectie-C
112
112
  キャッシュディレクトリ配列:(
113
113
  "/Users/user/Library/Developer/CoreSimulator/Devices/C89BA657-CB47-4142-ADAD-0278E32047CF/data/Containers/Data/Application/D0584736-5F37-4A87-87E4-83F29064D0E9/Library/Caches",
114
114
  "/Library/Caches",
@@ -122,7 +122,7 @@
122
122
 
123
123
  さて、先程のソースの`NSUserDomainMask`にカーソル当てて⌘クリックするとこんな定義に飛びます。
124
124
 
125
- ```
125
+ ```Objectie-C
126
126
  //NSPathUtilities.h
127
127
  typedef NS_OPTIONS(NSUInteger, NSSearchPathDomainMask) {
128
128
  NSUserDomainMask = 1, // user's home directory --- place to install user's personal items (~)
@@ -148,7 +148,7 @@
148
148
 
149
149
  因みに以下のように数値を直に記入しても同じ結果が得られると思います。C言語のenumは数値を置き換えたものだからです。
150
150
 
151
- ```
151
+ ```Objectie-C
152
152
  //キャッシュディレクトリを取得する
153
153
  NSArray *cachesArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, 1 | 2 | 4 | 8 , YES);//第二引数を1 | 2 | 4 | 8 にした。
154
154
  NSLog(@"キャッシュディレクトリ配列:%@", cachesArray);
@@ -182,16 +182,5 @@
182
182
 
183
183
 
184
184
 
185
- #【追記】userDomainMaskはなんで自分の定義元FileManager.SearchPathDomainMask型なのか!?
186
185
 
187
- 今もう一度調査して作成中です。最初の私の説明がトンチンカンなことをいっていたような気がして混乱させているかもしれません。今しばらくお待ち下さい。
188
186
 
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
-

3

追記にて、説明にて誤りがあったため修正

2017/01/14 03:31

投稿

SatoTakeshiX
SatoTakeshiX

スコア113

answer CHANGED
@@ -142,7 +142,8 @@
142
142
 
143
143
  1001(イチゼロゼロイチ)
144
144
 
145
- ならば`NSUserDomainMask`(10進法で1の数字)と`NSSystemDomainMask`(10進法で8の数値)が選択されていることがわかります。
145
+ ならば`NSUserDomainMask`(2進法で1桁目。10進法で1の数字)と`NSSystemDomainMask`(2進法で4桁目。10進法で8の数値)が選択されていることがわかります。
146
+
146
147
  2進数で各位に1があればそれが選択されているということが分かるのがビット演算で、NSSearchPathDomainMaskはそのようにしてディレクトリを選択しています。
147
148
 
148
149
  因みに以下のように数値を直に記入しても同じ結果が得られると思います。C言語のenumは数値を置き換えたものだからです。
@@ -155,8 +156,7 @@
155
156
  ```
156
157
 
157
158
  話をSwiftに戻します。
158
- Swift3になってから、APIドキュメントが整理されました。またSwift2まではFoundationライブラリーはObjective-Cのものを直接ブリッチしただけだったものをよりSwiftらしい書き方に変更されました。
159
- そこ直接ビット演算行うよりはOptionSetをつかったインスタンスのメソッドによる操作によって表現するようにりました。
159
+ Swift2から`OptionSetType`(Swift3`OptionSet`に改名)が追加されてこのビットマスク操作をインスタンスのメソッドによる操作でできるようにりました。
160
160
 
161
161
  上記のObjective-CのコードをSwiftに置き換えてみます。
162
162
 
@@ -171,14 +171,17 @@
171
171
 
172
172
  ```
173
173
  `FileManager.SearchPathDomainMask.localDomainMask`で変数`useMask`を作成し、`insert`メソッドで追加をしています。ビット演算は使っていません。
174
- どちらの書き方がいいかは個人によると思いますが、Swift3では「Swift2までC言語の関数をブリッチして呼び出していたものインスタンスメソッドによる操作に換える」アップデートされま
174
+ ビット演算を直接やるか`OptionSet`を採用してインスタンスによるメソッド操作に書き方にするかどちらがいいかは議論があるところですが、少なくとAppleFoundation開発者は「インスタンスによるメソッド操作にき方」がいいと思って`OptionSet`定義ているのだと思います
175
175
 
176
+ `SearchPathDomainMask`とは関係ないので完全に余談ですが、Swift3から「Swift2までC言語の関数をブリッチして呼び出していたものをインスタンスのメソッドによる操作に置き換える」方向でアップデートされました。
177
+ 「インスタンスによるメソッド操作に書き方」の方が受け入れられつつあります。
178
+
176
179
  [iOS][Swift] Swift 3.0の変更点まとめ
177
180
  http://dev.classmethod.jp/smartphone/iphone/implemented_proposals_for_swift3/
178
-
179
181
  のSE-0044: Import as Memberを参照してください。
180
182
 
181
183
 
184
+
182
185
  #【追記】userDomainMaskはなんで自分の定義元FileManager.SearchPathDomainMask型なのか!?
183
186
 
184
187
  今もう一度調査して作成中です。最初の私の説明がトンチンカンなことをいっていたような気がして混乱させているかもしれません。今しばらくお待ち下さい。

2

【追記】 iOSのアプリのフォルダ指定をビットマスクによって管理するとはどうゆうことなのか?

2017/01/14 02:20

投稿

SatoTakeshiX
SatoTakeshiX

スコア113

answer CHANGED
@@ -84,4 +84,111 @@
84
84
  extensionってコードの可読性を上げるために、追加の機能は全てextensionで書かれることがあり、Foundationライブラリーはその書き方にならっているので、こんな書き方になっていると予想します。
85
85
 
86
86
  --------
87
+ # 【追記】 iOSのアプリのフォルダ指定をビットマスクによって管理するとはどうゆうことなのか?
88
+
89
+ [ビットをどう使うかよく判らない人へ](http://qiita.com/satoshinew/items/566bf91707b5371b62b6)
90
+ ではビットフラグを作り、フラグを立てることで変数に複数の状態を表すことができると書かれています。
91
+ それを今回のSearchPathDomainMask例で提示します。
92
+
93
+ 突然ですが、今すぐXcodeで新しいプロジェクトを作成して、ViewControllerのviewDidloadで以下のコードを書いてください
94
+
95
+ ```objective-c
96
+ - (void)viewDidLoad {
97
+ [super viewDidLoad];
98
+ //キャッシュディレクトリを取得する
99
+ NSArray *cachesArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSLocalDomainMask | NSUserDomainMask | NSNetworkDomainMask | NSSystemDomainMask , YES);
100
+ NSLog(@"キャッシュディレクトリ配列:%@", cachesArray);
101
+ }
102
+
103
+ ```
104
+
105
+ `NSSearchPathForDirectoriesInDomains`関数の第一引数には検索するディレクトリを入れます。
106
+ 今回は`NSCachesDirectory`を指定してキャッシュディレクトリを取得します。
107
+ 第二引数はドメインマスクを指定します。今回は`NSLocalDomainMask | NSUserDomainMask | NSNetworkDomainMask | NSSystemDomainMask`とor演算をして、全て選択します。
108
+
109
+ これを実行するとこんな結果が得られると思います。
110
+
111
+ ```
112
+ キャッシュディレクトリ配列:(
113
+ "/Users/user/Library/Developer/CoreSimulator/Devices/C89BA657-CB47-4142-ADAD-0278E32047CF/data/Containers/Data/Application/D0584736-5F37-4A87-87E4-83F29064D0E9/Library/Caches",
114
+ "/Library/Caches",
115
+ "/System/Library/Caches"
116
+ )
117
+ ```
118
+ NSLocalDomainMaskとして`"/Users/user/Library/Developer/CoreSimulator/Devices/C89BA657-CB47-4142-ADAD-0278E32047CF/data/Containers/Data/Application/D0584736-5F37-4A87-87E4-83F29064D0E9/Library/Caches"`
119
+ NSUserDomainMaskとして`"/Library/Caches"`
120
+ NSSystemDomainMaskとして`"/System/Library/Caches"`
87
- いかがでしょうか?参考になりましたか?
121
+ の3つのディレクトリ取得ました
122
+
123
+ さて、先程のソースの`NSUserDomainMask`にカーソル当てて⌘クリックするとこんな定義に飛びます。
124
+
125
+ ```
126
+ //NSPathUtilities.h
127
+ typedef NS_OPTIONS(NSUInteger, NSSearchPathDomainMask) {
128
+ NSUserDomainMask = 1, // user's home directory --- place to install user's personal items (~)
129
+ NSLocalDomainMask = 2, // local to the current machine --- place to install items available to everyone on this machine (/Library)
130
+ NSNetworkDomainMask = 4, // publically available location in the local area network --- place to install items available on the network (/Network)
131
+ NSSystemDomainMask = 8, // provided by Apple, unmodifiable (/System)
132
+ NSAllDomainsMask = 0x0ffff // all domains: all of the above and future items
133
+ };
134
+
135
+ ```
136
+ `NS_OPTIONS`修飾子はObjective-CとSwiftを橋渡しする修飾子で、文法的にはC言語のenumになります。
137
+ (Objective-Cという言語は[]で囲われていない部分はC言語の文法で動く言語です。)
138
+ C言語のenumは数値に名前をつけられるものです。上記のソースでは「1という数値に`NSUserDomainMask`という名前を2という数値に`NSLocalDomainMask`を...以下略」としています。
139
+ なぜ2の階乗ごとの数値になっているかというと2進数で表した時に都合がいいからです。
140
+ この数値をビットマスクすることで複数のディレクトリを選択することができます。
141
+ 例えば、最終的なNSSearchPathDomainMaskの値が2進数で
142
+
143
+ 1001(イチゼロゼロイチ)
144
+
145
+ ならば`NSUserDomainMask`(10進法で1の数字)と`NSSystemDomainMask`(10進法で8の数値)が選択されていることがわかります。
146
+ 2進数で各位に1があればそれが選択されているということが分かるのがビット演算で、NSSearchPathDomainMaskはそのようにしてディレクトリを選択しています。
147
+
148
+ 因みに以下のように数値を直に記入しても同じ結果が得られると思います。C言語のenumは数値を置き換えたものだからです。
149
+
150
+ ```
151
+ //キャッシュディレクトリを取得する
152
+ NSArray *cachesArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, 1 | 2 | 4 | 8 , YES);//第二引数を1 | 2 | 4 | 8 にした。
153
+ NSLog(@"キャッシュディレクトリ配列:%@", cachesArray);
154
+
155
+ ```
156
+
157
+ 話をSwiftに戻します。
158
+ Swift3になってから、APIドキュメントが整理されました。またSwift2まではFoundationライブラリーはObjective-Cのものを直接ブリッチしただけだったものをよりSwiftらしい書き方に変更されました。
159
+ そこで直接ビット演算を行うよりはOptionSetをつかったインスタンスのメソッドによる操作によって表現するように鳴りました。
160
+
161
+ 上記のObjective-CのコードをSwiftに置き換えてみます。
162
+
163
+ ```swift
164
+ var useMask = FileManager.SearchPathDomainMask.localDomainMask
165
+ useMask.insert(.userDomainMask)
166
+ useMask.insert(.networkDomainMask)
167
+ useMask.insert(.systemDomainMask)
168
+
169
+ let cachesArray = NSSearchPathForDirectoriesInDomains(.cachesDirectory, useMask, true)
170
+ print(cachesArray)
171
+
172
+ ```
173
+ `FileManager.SearchPathDomainMask.localDomainMask`で変数`useMask`を作成し、`insert`メソッドで追加をしています。ビット演算は使っていません。
174
+ どちらの書き方がいいかは個人によると思いますが、Swift3では「Swift2までC言語の関数をブリッチして呼び出していたものをインスタンスのメソッドによる操作に置き換える」方向でアップデートされました。
175
+
176
+ [iOS][Swift] Swift 3.0の変更点まとめ
177
+ http://dev.classmethod.jp/smartphone/iphone/implemented_proposals_for_swift3/
178
+
179
+ のSE-0044: Import as Memberを参照してください。
180
+
181
+
182
+ #【追記】userDomainMaskはなんで自分の定義元FileManager.SearchPathDomainMask型なのか!?
183
+
184
+ 今もう一度調査して作成中です。最初の私の説明がトンチンカンなことをいっていたような気がして混乱させているかもしれません。今しばらくお待ち下さい。
185
+
186
+
187
+
188
+
189
+
190
+
191
+
192
+
193
+
194
+

1

ビットの説明記事を追加

2017/01/13 17:56

投稿

SatoTakeshiX
SatoTakeshiX

スコア113

answer CHANGED
@@ -10,6 +10,7 @@
10
10
  ```
11
11
  質問で書かれていた
12
12
  > SearchPathDomainMaskという構造体は、OptionSet型なのでしょうか??
13
+
13
14
  ですが、クラスの定義とごっちゃになっていそうなので、クラスの定義もお伝えすると
14
15
 
15
16
  ```
@@ -41,7 +42,11 @@
41
42
  >http://www.toyship.org/archives/2208
42
43
 
43
44
  どうやら、iOSのアプリのフォルダ指定をビットマスクによって管理しているようです。
45
+ ビット自体の説明は以下の記事がわかりやすいです。
44
46
 
47
+ >ビットをどう使うかよく判らない人へ
48
+ >http://qiita.com/satoshinew/items/566bf91707b5371b62b6
49
+
45
50
  # userDomainMask等の型指定について
46
51
 
47
52
  私も初めてこの形をみましたし、⌘+クリックの定義ファイルでは具体的な実装まではわからないのでなんとも言えないですが、