Month: August 2014

Swift: convenience initほぼ挫折

convenience initはほぼ挫折・中断して、先に進めています。

これでは、あとでまたここに戻ることになるのですが、飽きてきたので別のことをしています。

基本的なことなのですが、配列を初期化したあと、値を入れていくとき、0番目の配列に値を入れるには追加しかできないものなのでしょうか。これまでObjective-Cでは、0番目に入れると書いていたのですが、大きな勘違いだったようですね。

Objective-Cでは、たまたまうまく行っていたのでしょうか?

配列trTreeSavedPathの0番目に配列ttTreeSaveのinx2番目の中身を追加するとき、受け側にインデックスを使うと、そのオブジェクトができていないとき、置換できないのでエラーになるのはもっともな話ですが、改めてよくわかっていないことを再認識しました。

正しい例
Mesa.trTreeSavedPath    += ttTreeSave[inx2]

 

まちがった例
Mesa.trTreeSavedPath[0]    = ttTreeSave[inx2]

Swift: convenience init手強くてやり直し

とても向こう側に川岸があり、まるで岸が見えないので、海にいるのか、川にいたのか、違いがわからなくなってきています。

もう一度、最初からやりなおさないと、コンパイラがまともに動かなくなりました。convenience init自体は良さそうな感じなのですが、組み合わせが悪く、おまけに配列のAnyにobjectを入れようとする前後のところからおかしくなってしまいました。9月9日に新iPhoneが発表されるらしいですが、Yosemiteは10月で変わらずなのでしょうか?

FileNodeを最初からやり直すのが早道。

その間、次の3点を学習しました。

  • Any vs. AnyObject: AnyObjectはAnyよりも適用範囲が狭い。
    ① クラスのインスタンスに対して利用可能。
    AnyObjectIntBool などには利用不可。
  • is: is で変数・定数の型チェックができる。
    if abc is Int {  return } //abcがIntのときreturn
  • as?: 変換対象がその型に変換できない場合には nil が入る。
    ?なしで型変換ができないとき、エラーになる。

Swiftに関するメモ その7 – 型変換を参照。

Swift: convenience init(path node: String)

なかなかエラーが取れません。

とりあえず、こうすればエラーが取れたのですが、動かしてみないことにはなんとも言えません。

気になる点は

  • そもそもinit(path:String!)でいいのかどうか。
  • initの初期値の設定の仕方は?

スクリーンショット 2014-08-29 20.40.51

Swift:イニシャライズ? その2

以前、- (id)initWithPath:(NSString *)pathに対応するものがないと書いたのですが、今、FileNodeでこの問題に直面しています。

その後わかったことは、次の通りです。実際は、allocWithZoneとinitWithPathの2つの解が必要で、まず、initWithPathの方を解決しようとしています。早い話、initとconvenience initがどう違うのか? pathとnodeの違い?

もうひとつは、structを使うこととどう関係があるか?これらの組み合わせを確認したらどうだろうかというところでうろうろしています。

ひとつ疑問なのは、Objective-CはなぜinitWithPath:で返り値があってもOKなのでしょうか。

Objective-C

FileNode *copy = [[FileNode allocWithZone:zone] initWithPath:path];
FileNode *item = [[FileNode alloc] initWithPath:filePath];

候補


+ (instancetype)allocWithZone:(struct _NSZone *)zone

  • class func allocWithZone(_ zone: COpaquePointer) -> Self!

 + (instancetype)alloc

  • class func alloc() ->Self!

 – (id)initWithPath:(NSString *)path

 – (id)initWithPath:(NSString *)node

  • convenience init(path node: String)

 

Swift: イニシャライズ?

問題がいくつかあり、解決できたものと迂回せざるを得ないものが出てきました。

まず、イニシャライズについてです。

  • structはinit { }で初期値を設定します。これは確認事項で、問題ではありません。
    しかし、そのあと、classの下の変数に初期値を設定するのにinitを使ったら、ここから混乱し、収拾がつかなくなってしまったので、一旦、これはやめることにしました。
  • 問題が起きたのは、単純な話、配列の初期化です。サンプルプログラムでは、var trTreeSavedPath:[String]   = []と書いて問題がなかったのに、ループするようになりました。次のように修正したらOKになりました。

var trTreeSavedPath:[String]   = [String]()
var trIndex4wkArray:[Int]       = [Int]()
var wkArray:[NSDictionary]      = [NSDictionary]()

  • Initialization(初期化)を参考にしましたが、正直言って、自分のレベルが低いためか、よく理解できませんでした。

    もうひとつ、これはなぜそうなるのか、問題の原因が不明なのですが、サンプルプログラムではOKだったものがNGになりました。単なるエンコードの配列です。

let encodeTable:[UInt] = [NSUTF8StringEncoding,
        NSShiftJISStringEncoding, 
        NSJapaneseEUCStringEncoding]

  • これには時間をかけられないので、配列やめ、直接コンスタントを使うようしました。

それで、再び、windowsが表示されるようになりました。

NSTreeControllerのロジックを書いてあるFileNodeに制御が渡らないので、調べています。Objective-Cでは次のコードになります。

– (void)applicationDidFinishLaunching:(NSNotification *)aNotification {  
    [leftOfTable  setDataCell:[CustomCell new]];  
    NSString *wFilePath = [NSHomeDirectory() stringByAppendingFormat:@”/Desktop/MesaClip”];
    self.rootPath = [[FileNode alloc] initWithPath:wFilePath]; 

Swift:MesaClipperソースコード

とりあえずObjective-CからSwiftに一通り変更しました。

全くデバッグが終わっていないどころか、実行していないので何が起きるかわかりません。これから2週間かけて動くようにしたいと思っています。

  • 100%デバッグ未了です。UIにwebページが表示されるところまでは確認済み。
  • UIは暫定版です。
  • Objective-CとSwiftを対比しながら勉強するのに少しは役立つかもしれません。
  • 言い訳としては、Swiftへの変換がまちがっていたとしても、Swiftに変更するアイデアのひとつとして参考になれば幸いです。
  • 混乱させてしまうかもしれませんので、予め謝っておきます。
  • FileNodeはこれからもう一度コンバージョンし直します。あまりにいい加減になったままなので。
  • Objective-Cの2,000行が1,500行くらいの感じですが、ロジックを変えたところもあるので、一概にSwiftが小さくなるとは言えません。ただし、読みやすさと書きやすさは、はるかにSwiftが優れていると思います。

Swiftソースコードはここにあります。

Swift:Webkit 9 (NSTreeController横道4)

ようやくメインの残りがあと250行、それとFileNodeの200行になってきました。

Swiftでだいぶ書いたのでそれなりに少しわかってきました。きょうの夜には、一旦、暫定的にソースコードをアップできそうです。