回答編集履歴

5

誤記修正

2017/01/14 03:54

投稿

SatoTakeshiX
SatoTakeshiX

スコア113

test CHANGED
@@ -182,7 +182,7 @@
182
182
 
183
183
 
184
184
 
185
- 突然ですが、今すぐXcodeで新しいプロジェクトを作成して、ViewControllerのviewDidloadで以下のコードを書いてください
185
+ 突然ですが、今すぐXcodeで言語をObjective-Cで新しいプロジェクトを作成して、ViewControllerのviewDidloadで以下のコードを書いてください
186
186
 
187
187
 
188
188
 

4

整理

2017/01/14 03:54

投稿

SatoTakeshiX
SatoTakeshiX

スコア113

test CHANGED
@@ -128,7 +128,7 @@
128
128
 
129
129
 
130
130
 
131
- ```
131
+ ```swift
132
132
 
133
133
  class A {}
134
134
 
@@ -218,7 +218,7 @@
218
218
 
219
219
 
220
220
 
221
- ```
221
+ ```Objectie-C
222
222
 
223
223
  キャッシュディレクトリ配列:(
224
224
 
@@ -246,7 +246,7 @@
246
246
 
247
247
 
248
248
 
249
- ```
249
+ ```Objectie-C
250
250
 
251
251
  //NSPathUtilities.h
252
252
 
@@ -298,7 +298,7 @@
298
298
 
299
299
 
300
300
 
301
- ```
301
+ ```Objectie-C
302
302
 
303
303
  //キャッシュディレクトリを取得する
304
304
 
@@ -366,30 +366,8 @@
366
366
 
367
367
 
368
368
 
369
- #【追記】userDomainMaskはなんで自分の定義元FileManager.SearchPathDomainMask型なのか!?
369
+
370
-
371
-
372
-
373
- 今もう一度調査して作成中です。最初の私の説明がトンチンカンなことをいっていたような気がして混乱させているかもしれません。今しばらくお待ち下さい。
370
+
374
-
375
-
376
-
377
-
378
-
379
-
380
-
381
-
382
-
383
-
384
-
385
-
386
-
387
-
388
-
389
-
390
-
391
-
392
-
393
-
394
-
395
-
371
+
372
+
373
+

3

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

2017/01/14 03:31

投稿

SatoTakeshiX
SatoTakeshiX

スコア113

test CHANGED
@@ -286,7 +286,9 @@
286
286
 
287
287
 
288
288
 
289
- ならば`NSUserDomainMask`(10進法で1の数字)と`NSSystemDomainMask`(10進法で8の数値)が選択されていることがわかります。
289
+ ならば`NSUserDomainMask`(2進法で1桁目。10進法で1の数字)と`NSSystemDomainMask`(2進法で4桁目。10進法で8の数値)が選択されていることがわかります。
290
+
291
+
290
292
 
291
293
  2進数で各位に1があればそれが選択されているということが分かるのがビット演算で、NSSearchPathDomainMaskはそのようにしてディレクトリを選択しています。
292
294
 
@@ -312,9 +314,7 @@
312
314
 
313
315
  話をSwiftに戻します。
314
316
 
315
- Swift3になってから、APIドキュメントが整理されました。またSwift2まではFoundationライブラリーはObjective-Cのものを直接ブリッチしただけだったものをよりSwiftらしい書き方に変更されました。
316
-
317
- そこ直接ビット演算を行うよりはOptionSetをつかったインスタンスのメソッドによる操作によって表現するようにりました。
317
+ Swift2から`OptionSetType`(Swift3`OptionSet`に改名)が追加されてこのビットマスク操作をインスタンスのメソッドによる操作でできるようにりました。
318
318
 
319
319
 
320
320
 
@@ -344,7 +344,13 @@
344
344
 
345
345
  `FileManager.SearchPathDomainMask.localDomainMask`で変数`useMask`を作成し、`insert`メソッドで追加をしています。ビット演算は使っていません。
346
346
 
347
+ ビット演算を直接やるか`OptionSet`を採用してインスタンスによるメソッド操作に書き方にするかどちらがいいのかは議論があるところですが、少なくともAppleのFoundation開発者は「インスタンスによるメソッド操作に書き方」がいいと思って`OptionSet`で定義しているのだと思います。
348
+
349
+
350
+
347
- どちら書き方がいいかは個人よると思いますが、Swift3では「Swift2までC言語の関数をブリッチして呼び出していたものをインスタンスのメソッドによる操作に置き換える」方向でアップデートされました。
351
+ `SearchPathDomainMask`とは関係ないで完全余談ですが、Swift3から「Swift2までC言語の関数をブリッチして呼び出していたものをインスタンスのメソッドによる操作に置き換える」方向でアップデートされました。
352
+
353
+ 「インスタンスによるメソッド操作に書き方」の方が受け入れられつつあります。
348
354
 
349
355
 
350
356
 
@@ -352,14 +358,14 @@
352
358
 
353
359
  http://dev.classmethod.jp/smartphone/iphone/implemented_proposals_for_swift3/
354
360
 
355
-
356
-
357
361
  のSE-0044: Import as Memberを参照してください。
358
362
 
359
363
 
360
364
 
361
365
 
362
366
 
367
+
368
+
363
369
  #【追記】userDomainMaskはなんで自分の定義元FileManager.SearchPathDomainMask型なのか!?
364
370
 
365
371
 

2

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

2017/01/14 02:20

投稿

SatoTakeshiX
SatoTakeshiX

スコア113

test CHANGED
@@ -170,4 +170,220 @@
170
170
 
171
171
  --------
172
172
 
173
+ # 【追記】 iOSのアプリのフォルダ指定をビットマスクによって管理するとはどうゆうことなのか?
174
+
175
+
176
+
177
+ [ビットをどう使うかよく判らない人へ](http://qiita.com/satoshinew/items/566bf91707b5371b62b6)
178
+
179
+ ではビットフラグを作り、フラグを立てることで変数に複数の状態を表すことができると書かれています。
180
+
181
+ それを今回のSearchPathDomainMask例で提示します。
182
+
183
+
184
+
185
+ 突然ですが、今すぐXcodeで新しいプロジェクトを作成して、ViewControllerのviewDidloadで以下のコードを書いてください
186
+
187
+
188
+
189
+ ```objective-c
190
+
191
+ - (void)viewDidLoad {
192
+
193
+ [super viewDidLoad];
194
+
195
+ //キャッシュディレクトリを取得する
196
+
197
+ NSArray *cachesArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSLocalDomainMask | NSUserDomainMask | NSNetworkDomainMask | NSSystemDomainMask , YES);
198
+
199
+ NSLog(@"キャッシュディレクトリ配列:%@", cachesArray);
200
+
201
+ }
202
+
203
+
204
+
205
+ ```
206
+
207
+
208
+
209
+ `NSSearchPathForDirectoriesInDomains`関数の第一引数には検索するディレクトリを入れます。
210
+
211
+ 今回は`NSCachesDirectory`を指定してキャッシュディレクトリを取得します。
212
+
213
+ 第二引数はドメインマスクを指定します。今回は`NSLocalDomainMask | NSUserDomainMask | NSNetworkDomainMask | NSSystemDomainMask`とor演算をして、全て選択します。
214
+
215
+
216
+
217
+ これを実行するとこんな結果が得られると思います。
218
+
219
+
220
+
221
+ ```
222
+
223
+ キャッシュディレクトリ配列:(
224
+
225
+ "/Users/user/Library/Developer/CoreSimulator/Devices/C89BA657-CB47-4142-ADAD-0278E32047CF/data/Containers/Data/Application/D0584736-5F37-4A87-87E4-83F29064D0E9/Library/Caches",
226
+
227
+ "/Library/Caches",
228
+
229
+ "/System/Library/Caches"
230
+
231
+ )
232
+
233
+ ```
234
+
235
+ NSLocalDomainMaskとして`"/Users/user/Library/Developer/CoreSimulator/Devices/C89BA657-CB47-4142-ADAD-0278E32047CF/data/Containers/Data/Application/D0584736-5F37-4A87-87E4-83F29064D0E9/Library/Caches"`
236
+
237
+ NSUserDomainMaskとして`"/Library/Caches"`
238
+
239
+ NSSystemDomainMaskとして`"/System/Library/Caches"`
240
+
173
- いかがでしょうか?参考になりましたか?
241
+ の3つのディレクトリ取得ました
242
+
243
+
244
+
245
+ さて、先程のソースの`NSUserDomainMask`にカーソル当てて⌘クリックするとこんな定義に飛びます。
246
+
247
+
248
+
249
+ ```
250
+
251
+ //NSPathUtilities.h
252
+
253
+ typedef NS_OPTIONS(NSUInteger, NSSearchPathDomainMask) {
254
+
255
+ NSUserDomainMask = 1, // user's home directory --- place to install user's personal items (~)
256
+
257
+ NSLocalDomainMask = 2, // local to the current machine --- place to install items available to everyone on this machine (/Library)
258
+
259
+ NSNetworkDomainMask = 4, // publically available location in the local area network --- place to install items available on the network (/Network)
260
+
261
+ NSSystemDomainMask = 8, // provided by Apple, unmodifiable (/System)
262
+
263
+ NSAllDomainsMask = 0x0ffff // all domains: all of the above and future items
264
+
265
+ };
266
+
267
+
268
+
269
+ ```
270
+
271
+ `NS_OPTIONS`修飾子はObjective-CとSwiftを橋渡しする修飾子で、文法的にはC言語のenumになります。
272
+
273
+ (Objective-Cという言語は[]で囲われていない部分はC言語の文法で動く言語です。)
274
+
275
+ C言語のenumは数値に名前をつけられるものです。上記のソースでは「1という数値に`NSUserDomainMask`という名前を2という数値に`NSLocalDomainMask`を...以下略」としています。
276
+
277
+ なぜ2の階乗ごとの数値になっているかというと2進数で表した時に都合がいいからです。
278
+
279
+ この数値をビットマスクすることで複数のディレクトリを選択することができます。
280
+
281
+ 例えば、最終的なNSSearchPathDomainMaskの値が2進数で
282
+
283
+
284
+
285
+ 1001(イチゼロゼロイチ)
286
+
287
+
288
+
289
+ ならば`NSUserDomainMask`(10進法で1の数字)と`NSSystemDomainMask`(10進法で8の数値)が選択されていることがわかります。
290
+
291
+ 2進数で各位に1があればそれが選択されているということが分かるのがビット演算で、NSSearchPathDomainMaskはそのようにしてディレクトリを選択しています。
292
+
293
+
294
+
295
+ 因みに以下のように数値を直に記入しても同じ結果が得られると思います。C言語のenumは数値を置き換えたものだからです。
296
+
297
+
298
+
299
+ ```
300
+
301
+ //キャッシュディレクトリを取得する
302
+
303
+ NSArray *cachesArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, 1 | 2 | 4 | 8 , YES);//第二引数を1 | 2 | 4 | 8 にした。
304
+
305
+ NSLog(@"キャッシュディレクトリ配列:%@", cachesArray);
306
+
307
+
308
+
309
+ ```
310
+
311
+
312
+
313
+ 話をSwiftに戻します。
314
+
315
+ Swift3になってから、APIドキュメントが整理されました。またSwift2まではFoundationライブラリーはObjective-Cのものを直接ブリッチしただけだったものをよりSwiftらしい書き方に変更されました。
316
+
317
+ そこで直接ビット演算を行うよりはOptionSetをつかったインスタンスのメソッドによる操作によって表現するように鳴りました。
318
+
319
+
320
+
321
+ 上記のObjective-CのコードをSwiftに置き換えてみます。
322
+
323
+
324
+
325
+ ```swift
326
+
327
+ var useMask = FileManager.SearchPathDomainMask.localDomainMask
328
+
329
+ useMask.insert(.userDomainMask)
330
+
331
+ useMask.insert(.networkDomainMask)
332
+
333
+ useMask.insert(.systemDomainMask)
334
+
335
+
336
+
337
+ let cachesArray = NSSearchPathForDirectoriesInDomains(.cachesDirectory, useMask, true)
338
+
339
+ print(cachesArray)
340
+
341
+
342
+
343
+ ```
344
+
345
+ `FileManager.SearchPathDomainMask.localDomainMask`で変数`useMask`を作成し、`insert`メソッドで追加をしています。ビット演算は使っていません。
346
+
347
+ どちらの書き方がいいかは個人によると思いますが、Swift3では「Swift2までC言語の関数をブリッチして呼び出していたものをインスタンスのメソッドによる操作に置き換える」方向でアップデートされました。
348
+
349
+
350
+
351
+ [iOS][Swift] Swift 3.0の変更点まとめ
352
+
353
+ http://dev.classmethod.jp/smartphone/iphone/implemented_proposals_for_swift3/
354
+
355
+
356
+
357
+ のSE-0044: Import as Memberを参照してください。
358
+
359
+
360
+
361
+
362
+
363
+ #【追記】userDomainMaskはなんで自分の定義元FileManager.SearchPathDomainMask型なのか!?
364
+
365
+
366
+
367
+ 今もう一度調査して作成中です。最初の私の説明がトンチンカンなことをいっていたような気がして混乱させているかもしれません。今しばらくお待ち下さい。
368
+
369
+
370
+
371
+
372
+
373
+
374
+
375
+
376
+
377
+
378
+
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+
387
+
388
+
389
+

1

ビットの説明記事を追加

2017/01/13 17:56

投稿

SatoTakeshiX
SatoTakeshiX

スコア113

test CHANGED
@@ -21,6 +21,8 @@
21
21
  質問で書かれていた
22
22
 
23
23
  > SearchPathDomainMaskという構造体は、OptionSet型なのでしょうか??
24
+
25
+
24
26
 
25
27
  ですが、クラスの定義とごっちゃになっていそうなので、クラスの定義もお伝えすると
26
28
 
@@ -83,6 +85,14 @@
83
85
 
84
86
 
85
87
  どうやら、iOSのアプリのフォルダ指定をビットマスクによって管理しているようです。
88
+
89
+ ビット自体の説明は以下の記事がわかりやすいです。
90
+
91
+
92
+
93
+ >ビットをどう使うかよく判らない人へ
94
+
95
+ >http://qiita.com/satoshinew/items/566bf91707b5371b62b6
86
96
 
87
97
 
88
98