twitterのOAuth画面の言語について

bengottlieb / Twitter-OAuth-iPhone
https://github.com/bengottlieb/Twitter-OAuth-iPhone

このライブラリを使ってOAuthの実験をしていたんですが、初回OAuth登録時のユーザーログイン画面の言語がどうしても英語になってしまって悩んだりしたのでメモとして書置きます。

さんざん悩んだ結果iOSシミュレーターではなく自前のiPhone4で接続したらうまくいって気づきました。
iOSシミュレーターは標準状態では「英語」の言語設定になっていたのです!!!(なんだってー

iOSの言語が英語→WebView接続時のGETリクエストが英語→twitterが英語画面を表示

簡単ですね。
なんか他にも弊害とかありそうな気がするので日本(向け)の開発者は早めに設定を変えておいた方が吉だと思います。

顔認識

笑い男の技術力を手に入れたいと思い顔認識を調べていましたがOpen-CVのHaarウェーブレットのあたりで length >>= 1 という謎の演算式にぶちあたり、あれ?何これと思ってちょっとコード書いたり。

なんてことはなかったです。
a += 1 で a = a + 1と同じで a >== 1は a = a >> 1だった。

なんか10進数から2進数への変換プログラム例があっちではwhile(1)とかやってたり、こっちでは何故か10進数変数で2進数を表現していたり、わざわざ配列使ってたりしてうんざりしたので、電子世界の迷い人がより良い答えにたどり着けるよう祈りつつ下記に乗せておきます。

10進数を2進数で表示するC言語コード

void printbit(int i){
if(i>>1)printbit(i>>1);
printf("%d", i%2 ? 1:0);
}

小賢しい手を使わないと下記です。

void printbit(int i){

if( i /2 > 0) printbit( i / 2);

if(i % 2 == 1) printf("%d", 1);
else printf("%d", 0);

}

Objective-C 2.0 及びARCにおけるメモリ管理の妄想

たぶんこんな感じなのかなーと妄想。
後でライブラリの実装みてみよう。

ガベージコレクションが未実装のC言語の場合
malloc/dealloc、new delete で直接解放
カプセル化されたSDKの場合一般的に Object->Release() で解放
・オブジェクトの参照はメモリアドレスのコピーを行うだけ

この場合、解放=メモリ上からの削除なのでオブジェクトのポインタを多岐にわたって参照していた場合にAccess Violationが発生する可能性が高くなる。(しかもアドレスだけしか表示されなかったり、強制終了がメインなのでデバッグが大変。)

寮内でのゲームの貸し出しに例えると、
・Aさんがゲームを買ってきて「ぼうけんのしょ」を作る。
・BさんがAさんと仲が良いので「ぼうけんのしょ」を作る。
・CさんはBさんと仲が良いので「ぼうけんのしょ」を作る。
・AさんはBさんがクリアしたのを確認してゲームを売りに行く。
・Cさんがゲームをプレイしようと思ったらゲームがもう無い!(Access Violation)

という感じですね。

さてここからは実装を見ていない妄想です。

iPhoneにおけるObjective-C 2.0の場合
・Pointerでオブジェクトを生成する際に必ず管理プールに登録してカウントを+1する
・オブジェクトの参照時に必ず管理プールに登録されたカウントを+1する
・オブジェクトの参照をやめる際にreleaseを呼ぶと管理プールに登録されたカウントを-1する
 ※C言語と違ってreleaseを呼んだ瞬間に解放することはない
GUI向け開発言語なので最初からメインループがあり、メインループの終了時にカウントが0になっているオブジェクトをメモリ上から解放する

恐らくこんな感じだと思うのですが、Objective-Cでプログラミングをしている限り、Pointerが曖昧になり、管理プールの存在にいたってはカプセル化により完全に隠蔽されているため実際の挙動がつかめない状況です。(importファイルのライブラリと実装状況を漁るしかない。)
このような実装にした理由としては、Objective-Cの名前にもある通りオブジェクト指向につくられた言語なので参照が多岐にわたる機会が非常に多いなかでAccess Violationを防ぐためでしょうか、最悪カウントが0にされないまま残っても動作は保証されます(メモリリーク)。またretainを忘れるとクラッシュする可能性が残っています。

寮内でのゲームの貸し出しに例えると、
・Aさんがゲームを買ってきて「ぼうけんのしょ」を作る。
 ケースの中に「プレイ中」の付箋紙をいれておく。
・BさんがAさんと仲が良いので「ぼうけんのしょ」を作る。
 ケースの中に「プレイ中」の付箋紙をいれておく。(現在2枚)
・CさんはBさんと仲が良いので「ぼうけんのしょ」を作る。
 ケースの中に「プレイ中」の付箋紙をいれておく。(現在3枚)
・Bさんがゲームをクリアする。
 ケースの中から「プレイ中」の付箋紙を取り出す。(現在2枚)
・Aさんがゲームを売りに行こうとするが、
 「プレイ中」の付箋紙が2枚、Aさんの分ともうひとり誰かプレイ中の人の分があるのでやめる。
・Cさんがゲームをクリアする。
 ケースの中から「プレイ中」の付箋紙を取り出す。(現在1枚)
・Aさんがゲームを売りに行く。
 ケースの中に「プレイ中」の付箋紙が1枚しかない状態なので問題ない。

実際の解放者はAさんではないので妄想実装との違いがありちょっと苦しいですが、こんな感じですね。

ARCの場合
・Pointerでオブジェクトを生成する際に必ず管理プールに登録してカウントを+1する
・オブジェクトの参照時にコンパイラがスコープを把握した上で管理プールのカウントを+1する
・オブジェクトがスコープ外に出た際に管理プールのカウントを-1する
・生成後のカウント部分をコーディングしようとするとエラーになる
・ルールを使いたくない時はstrongやweakなどの特別な修飾子を使う

これにより可視コードを減らすとともにObjective-C 2.0の場合に記載した赤字部分がほぼ解消されます。
ルールが増えた分、特殊な場合の制約が生じてしまいます。
また、初心者にとっての敷居が低くなりますが、その分メモリ管理の把握が非常に難しいという弊害があると思います。
トータルとしては一長一短というところでしょうか。

冗長になってしまいますのでたとえを省略しますが、妖精さんがクリア状況を常に把握して付箋紙を入れてくれる感じですね。

viewの動的な切り替えのメモ

1/31追記:具体的には下記手順で切り替えを進めて行くと最初に挿入されたUIViewのみタッチ判定が聞かなくなってしまいました。(IntefaceBuilderの使い方のせいかもしれませんが..)
ですので今はNavigationControllerをつかいつつUIを表示しない形式ですすめています。
※ただしスタック管理をしようとすると色々難しいかも。


1/28追記:下記ですが結果的に不健全な思想のもとでとある不具合等も抱えてしまったので、参考にしないほうがいいです。

>removeFromSuperview
>Unlinks the receiver from its superview and its window, and removes it from the responder chain.


AppDelegate.window.rootViewControllerにViewController.viewを登録。
InterfaceBuilderでViewController.view にFirstView(UIView)を登録。
またViewControllerの@propertyとして


@property (nonatomic, strong) IBOutlet FirstView *firstView;
@property (nonatomic, strong) IBOutlet SecondView *secondView;


を定義してInterfaceBuilder上の2つのUIViewと結びつける。
※InterfaceBuilder上のClassの手入力が必要。

この状態からFirstViewを破棄しようとして、
[ViewController.view removeFromSuperview]を呼んでしまうと
windowレベルで何かが書き変わりアウト。


ViewController.view = secondView;


でセーフ。


ちなみに@property宣言でstrongの部分をweakにするとsecondViewの生成後にsecondView=nilが発生しアウト。
ARCだともう動的管理とかいっさいがっさい考えないで無心でstrongした方がいいのかもしれない。


サンプルコード
He_352076.zip

符計算アプリ - 計算完成!

という感じで計算部分が完成たので、Infoとか弄ったりしてるところです。
tweet見直してみても、前回以降大きな難所は特になかったので、とりあえず符計算から点数計算へもっていく部分を軽く解説します。


1 .「子or親」×「ロンorツモ」×「 20、25、30〜110符それぞれの配列を作成

 ※5翻以上は符によらず固定なので20符のみ13翻まで作成し、25符〜110符は4翻まで作成
 ※子のツモは親の支払い、子の支払いに分けて作成

2 . 表示箇所で場面ごとのArrayを参照。5翻以上は問答無用で20符の配列を参照。


今日からInfo部分を弄っていて、トランジションアニメーションでくるっと回転させたり実験しています。
オーガナイザでどう頑張ってもアニメーション後のSSしか撮れないので、アニメーション中の撮影は無理っぽいです。それにしても、視覚的に訴える部分を作るのは楽しいですね〜。

味付けが終わったら、ボロボロのメモリ管理を見直して、無料で登録だー。

ちょっと寄り道 - 符計算アプリ

昨日から麻雀用の符計算アプリに着手し始めました。
TableViewやCustomCellについての知識や応用がぐんぐん向上していって勉強用には最適です。

さてさて前回の日記で「明日試してみて〜」とか書いた件ですが、
今回の符計算アプリで遭遇したので軽くメモっておきます。

・今作っている符計算の構造
 window
 -> FukeisanViewController (rootViewController)
  -> FuSelectViewController( UITableViewController)
    - HansuuCell (UITableViewCell)
    - KotsuCell (UITableViewCell)... etc


上記の構造で作っていますが、HansuuCellでユーザーが翻数を変更したときに、HansuuCell自体の数値を更新するのはもちろんの事、FukeisanViewController上の計算結果も更新しなければなりません。
調べてみた所方法が2つありました。


1.Delegateを作成する (よくわからないけど、汎用性に乏しそう)
2.KotsuCellにFukeisanViewConrollerのポインタを持たせる(今回の方法)


今回は汎用性に優れている2の方法を使っていまのところうまく動いているので手順を書いておきます。


<手順>
1. @property (nonatomic, assign) id rootFuView; もろもろをFuSelectViewControllerとKotsuCellに追加。
 ※nonatomic、assignで正しいかどうかはあまりよくわかっていません。

2.FuSelectViewControllerの初期化後に fuSelectViewController.rootFuView = self;
 KotsuCellの初期化後に cell.rootFuView = self.rootFuVuew;
 とやりポインタの受け渡し。

3.KotsuCell内の任意の関数内で
 FukeisanViewController *root = self.rootFuView; 後、
 [root refreshPoint];とか好きなように使う。


今回、NSInteger型の各箇所の符の値もFukeisanViewControllerのものを借りるかたちを取ったのですが、手順3の型宣言→ポインタの受け渡しが無い場合に「そんな関数ねーよ!」とお叱りを受けました。
idを使うときは一度明文化の上、委譲していおいて損は無さそうです。

というわけで、前回のTabBarControllerの上にViewを表示したい件についてもこれを生かせばなんとかなりそうです。
設定用のViewだけなので方法1のDelegateに挑戦するのもありかな。

TabBarControllerの復習

前回の日記で書いた事をもうちょっと分かりやすく書いておきます。
通常、window = [[UIWindow alloc] initWithFrame:bounds];で取得したwindowにaddSubviewする形でviewを追加し、そのviewにさらに子となるviewを追加、さらに追加という形でviewを構築していきますが、


UITabBarController.viewはwindowに追加しなければならない


という事らしく、windowに追加した子viewに追加しても全然表示されなくなります。
※もしかしたら表示する裏技があるかもしれません。
となると、TabBarと同じ階層にViewを追加して上手くコントロールするには、

@interface RootViewController : UITabBarController {
UIWindow *mainWindow;
}
あるいは

@interface RootViewController : UIViewController {
UIWindow *mainWindow;
UITabBarController tabBarView;
}

として、windowの参照を持たせる事が必要になってきそうです。
このRootViewControllerさえ作ってしまえばview同士の連携もうまくいけそうですね。

後は参照渡しの方法ですが、いつも通り@propertyで渡しておけば良さそうに思うので、
明日ちょっと弄ってみて、分かり次第ここに書いておきます。