JavaScriptからObjective-Cに変換されたNSArrayで配列の要素にアクセスする際の注意

11/7追記:WebKit DOM Programming TopicsのCalling Objective-C Methods From JavaScriptに書いてあった。WebKit側の資料しか見てなかったから気づかなかったorz

Other JavaScript objects are wrapped as WebScriptObject instances.

As an exception, JavaScript arrays cannot be cleanly mapped to NSArray objects because they are a hybrid between a numerically-indexed array and an associative array. To avoid loss of data during the mapping, you must instead use the webScriptValueAtIndex: and setWebScriptValueAtIndex:value: methods.

webScriptValueAtIndex:とsetWebScriptValueAtIndex:value:ね。


JavaScriptのArrayはObjective-CではNSArrayにマッピングされる。
しかし、要素へのアクセスで、最近出来るようになった添字アクセスを使うと取得出来ない。

- (void)callFromJavaScript:(NSArray *)array
{
  //NG
  //NSString *firstElement = array[0];
  //OK.
  NSString *firstElement = [array objectAtIndex:0];
}

objectAtIndex:を使えば問題なし

-[WebScriptObject objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x1079432c0

WebScriptObjectが呼ばれてますね。
添字が数値なら- objectAtIndexedSubscript:が呼ばれて添字アクセスの記法を処理するわけだけど、WebScriptObjectは解決できないので駄目だと。
Objective-C側に引数で渡されて来た時点でNSArrayになっているわけではなく、JavaScriptオブジェクトの環境をラップしているWebScriptObjectがごにょごにょと処理しているんですね。


追記:と、いうことは、WebScriptObjectにカテゴリで- objectAtIndexedSubscript:と、- objectForKeyedSubscript:を追加すれば。でもそのうち実装されそうな気がするので、このままに。