Swift

Swift:設計ミス

配列のデータ構造の持ち方を変更しました。

そもそもという話をすると、配列に定義してあるキーワードと一致したとき、そのvalueによって個々の変換が必要なとき、3次元配列にするとreadのアクセスは問題ないのですが、writeのアクセスが発生する場合、処理が面倒になるので、変換テーブルだけを別の配列で定義していました。

しかし、これだとやたらとif文によって判別する処理が出てくるため、行数も増え煩雑になってしまいます。それで、処理の種類は、①変換しない、②プログラムによる変換、③変換テーブルによる変換、④キー不一致で変換しないの4種類らしいということはわかっていたので、3次元配列(NSArray)に変更し、処理の種類を入れ込むことにしました。

let trArrayCGI:NSArray  = [  
 [“Int”,  “😄”, “ColorModel”,  “色空間”, “”, [ ]],
 [“Int”,  “😄”, “PixelWidth”,   “画像横幅(ピクセル)”, “”, [ ]],
 [“Int”,  “😄”, “PixelHeight”,  “画像高さ(ピクセル)”, “”, [ ]],  
 [“Int”,  “😄”, “Orientation”,  “画像方向”, “”, [  
    [“1”, “1: Horizontal (Normal)”, “1: 水平 (ノーマル)”],  
    [“2”, “2: Mirror Horizontal”,    “2: 左右反転”]

これは基本設計レベルの大きな方針変更であり、修正に2日間を要しました。しかし、休み休み慎重にやったので、ほとんど問題なく動きました。ライン数が減り、プログラムが単純化できました。

それでも、まだ腑に落ちない問題は、入力辞書を読み込み、キーを.keyで取り出したあと、.valueの取り出しのとき、データ型がAnyobject相当で不明であることにより型変換エラーが起こさないで取り出す方法がわからないことでした。文字列か数値または浮動小数点か、配列のいずれかなのですが、それを知る方法がわからなかったのです。もちろんworkaroundとして”\(wItem.value)”のような表現で文字列化できていたので、決定的なクリティカルイッシューではないのですが、何となく嫌な感じでした。

しかし、これは意外と単純で、たとえば配列かどうかはif (pInDic[cm.rcKey] as? NSArray) == nil(pInDic辞書の中のcm.rcKeyのvalueはnilか)のように聞き、nilでないなら配列、nilなら文字列か数値とすればいいことがわかりました。

 if wItem.value as? String != nil {
   cm.rcValue  = wItem.value as! String
} else  if (pInDic[cm.rcKey] as? NSArray) == nil {  
   cm.rcValue  = String(wItem.value as! Int)

前述した通り、この処理は、元々、“\(wItem.value)”のような表現で文字列に変換していたものです。これが真っ当な方法かどうかわからなかったので、Anyobjectの型を知る方法がないか、ずっと考えていた次第です。

Categories: Swift, 技術