UITableViewCellの更新について

UITableViewCell内で受け取った値の更新をしようとしたら嵌ったのでメモ。

cellだけ更新したい場合は、reloadRowsAtIndexPaths:withRowAnimation:でcellを指定して

UITableView* myTableView = テーブルビュー;
for (int i = 行数 - 1; i >= 0; --i) {
	if (何らかの条件) {
		NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:0];
		NSArray* indexPaths = [NSArray arrayWithObject:indexPath];
		[myTableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
	}
}
あかばね式 [iPhone]UITableViewで1行単位で行のリフレッシュを行う方法


というような感じでできる…はずがcellの値は更新されないし、画面遷移しない状況で使うのはまずいのか表示が崩れた。
ということで調べた結果、setNeedsLayoutに変更。

(中略)
[headingCell setNeedsLayout];
特定のUITableViewCellだけ再描画 - nkmrshnの日記


表示が崩れることはなくなったけど、相変わらず更新がかからない…
NSLogでは受け取れているのが確認できるし、実際cellを一度画面外に追いやって再描画させると出てくる。
ここでしばらく嵌ること小一時間。
performSelectorOnMainThread:withObject:waitUntilDone:にsetNeedsLayoutを突っ込むことで解決。

データの更新などを行った後、スレッド内で単に
[(UITableView)tableView reloadData]
とやると落ちてしまう。そこで以下のようなコードを記述することによって、データの再読み込み処理をメインスレッドに戻して処理させるようにする。
[(UITableView)tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
http://ebisu.surbiton.jp/sysblog/2012/04/uitableview.html


先人に感謝。

OSC Library in iOS

iPhoneでOSC扱う時に良さげなライブラリがあるようなないような。
ライセンスが万が一の時に引っかかりそうなのが多いところがちょっと気になる。
OSCライブラリの比較 | akalogue


ちょい前にlibloを使ったけど、それほど苦労せず扱えたので比較的おすすめ。
というかまだこれしか使ったことない。
liblo: Lightweight OSC implementation


今回はObjective-Cに最適化してあるのを使ってみる。(libloはC)
とりあえずObjOSCを選択。が、えらく古いためかプロジェクト開けなくてBuildできないし、ぐぐって回避方法とってもエラー出たので諦めた。
IAMASの赤松先生はVVOSCを使っているようなので、倣ってみる。
vvopensource - Project Hosting on Google Code

まずはヘッダをインポート。
#import "VVOSC.h"

そしてOSCマネージャを作って、デリゲートを指定。
OSCManager *manager = [[OSCManager alloc] init];
manager.delegate = self;

出力ポートを作って送信。
OSCOutPort *outPort = [manager createNewOutputToAddress:@"127.0.0.1" atPort:1234];
	
OSCMessage *message = [OSCMessage createWithAddress:@"/test"];
[message addInt:100];
[outPort sendThisPacket:[OSCPacket createWithContent:message]];

入力ポートは作るだけ。
OSCInPort *inPort = [manager createNewInputForPort:1234];

実際に受信するとデリゲートが呼ばれる。
- (void) receivedOSCMessage:(OSCMessage *)m
{	
    NSString *address = m.address;
    OSCValue *value = m.value;
	
    if ([address isEqualToString:@"/test"])
        NSLog(@"%d", value.intValue);
}
iOSでVVOSC | akalogue

楽ちん。


送信するだけなら気にしなくていいんだけど、受信する際にはデバイスIPアドレスが必要。
↓で取得は出来るけどPrivate APIなので申請用アプリ厳禁仕様。

[[NSHost currentHost] addresses];


調べれば色々出てくる中から、今回は[twitter:@akisutesama]が公開してるクラスを選択。
Objective-Cラッパーなのでぱっと使えるし、MITライセンスなので気兼ねする必要なし。
ありがとうネ申。
A-Liaison BLOG: iPhone / iPad でIPアドレスやMACアドレスを取得するクラスを書いてみた

NSLog(@"Device IP:%@", [[NetworkInformation alloc] init].primaryIPv4Address);

で無事確認。