人生初のコミックマーケット(C83)に参加

会社の同僚が何人か出展するとのことで、生まれて初めてコミケに一人で行ってみることにしました。 

会場の様子

こちらが会場となる国際展示場。到着したのは14:30くらい。ぎゅうぎゅう、というわけではないけど、やっぱりかなり人が多かったです。

f:id:kenmaz:20121229143719j:plain

どこへいったらいいかも分からないでの、とりあえず同僚のCさんが売り子をしている場所まで向かうことに。Cさんのツイッターをみると「@土曜東W12a」(記号は適当)みたいなことを書いてあったので、それを頼りに探す。

会場は「東」「西」の二つのエリアに分かれている様子。目的地は東っぽいのでそちらに向かう。西にはいったい何があったんだろう。

東エリアに到着。

f:id:kenmaz:20121229144516j:plain

エスカレーターを下ると広いホールを発見。壁に大きく「A」とか「Z」とか「あ」とか巨大な張り紙がしてある。これを頼りに目的地を探せばいいわけね。

f:id:kenmaz:20121229144605j:plain

最初に入ったホールとは別にもう一つ大きいホールがあって、そちらに目的地を発見。全部で2ホールなのかな?

各売り場は「サークル」単位で長机が割り当てられていて、そこに例の「薄い本」が並べられていた。サークルっていうくらいだから何人かでわいわいやっているのかなーと思ったけどCさんは一人でぽつねんとパイプイスに座っておられた。ちなみに他の同僚はみんな3日目の出展のようだ。残念。

残念ながらCさん作の薄い本は僕の趣向には合わなかったため購入は見送らせていただいた。少し雑談したあと、会場内を散策へ。

ホール内には長机がこれでもかというほど並べられており、全てのサークルを回ることは無理そうな感じだった。通常は事前にカタログを購入してお目当てのサークルを探してから計画的に回るものらしいが、今回はひたすら歩いてみて回ることにした。 

感想

コミケというと「二次創作のオタクっぽい同人マンガが売り買いされている場所」というイメージがあった。実際に小一時間会場を見て回った印象はこんな感じ。

  • 美少女二次創作マンガ、的な本がやはり多い
  • 大体会場の1/3くらいは、売り手も書い手も女子。本の内容はまあ腐女子系というのだろうか、ボーイズラブ的な、少女漫画的な、そんな感じ
  • もう1/3は、オタク男子のための萌え系っぽい、いかにもって感じの本。売り手買い手もそんな感じ
  • のこり1/3は、マンガや萌えではなく、たとえば旅行記、写真集、評論、模型、とか、わりと一般趣味書籍っぽい感じ
  • ゲームとか、ワンピースのようなメジャーコンテンツの二次創作はあまり見られなかった。もしかして3日間でジャンル分けがされているんだろうか。
  • 過激なエロとか暴力とかそういうのもあんまりなく、いたって平和的なコンテンツが多かったような印象

また会場自体に関しては以下の点が気になった。

  • 各サークルは列ごとにジャンル分けされている。島ではなく列ごとに分けられているっぽい。このおかげで、左右をきょろきょろしながら真ん中の通路をあるけば、大体この列はこんなジャンルの列なのね、ってことが探しやすくなっている。
  • ボランティア?っぽい人たちが大量にいて、会場の見回りをしたり、本部っぽいところで案内をしたりしている。ボランティなのかな?お金貰っているのかな?
  • コスプレイヤーはどこに!?
  • 16:00に終了。会場内全員で謎の三本締め。ほんわかした。

戦利品

そういうわけで、誰の案内もなく、一人でコミケに潜入して、よく分からないところも多々ありつつも、2時間くらい滞在した。買ったものは以下。

f:id:kenmaz:20121230020116j:plain

大阪と東京の高層ビルの写真とひとことが書かれた本。装丁がかなりしっかりしている。僕も結構高層ビルはすきなので楽しめた。東京の「環状2号線プロジェクト」と「大阪東京海上日動ビル」が気になったのでいつか確認しにいこう。あと、やっぱり六本木ヒルズの森タワーは好きだ。

発行:超高層ビルを愛でる会。¥400くらい。

f:id:kenmaz:20121230020202j:plain

ミニ四駆の(再)入門書。かなりボリュームのある一冊。小学校の遠足のしおりのような、手作り感あふれる装丁。最近のミニ四駆シャーシの動向から、作り方・チューンナップのコツ、そして公式大会に出場するまでの流れまでがぎっしり書かれている。小学校3,4年くらいのときに2度ほど公式大会にでたことがあるけど、公式大会ならではの巨大なコースはわくわくしますね。機会と気力があればミニ四駆、久しぶりに触ってみたい。

発行:犬神研究所。¥400くらい

f:id:kenmaz:20121230020148j:plain

工場から、官公庁、酒造、東京証券取引所、皇居、など関東のさまざまなスポットに関するレポートがまとめられたもの。いかにも面白そうな内容だったので1,2巻まとめて買った。さらにコカコーラ工場見学の経験をもとに書かれた「MMRコカコーラの陰謀」というマンガも購入。

発行:とこしえ工房。¥200〜¥300くらい。

 

以上、3サークルで買い物しました。まずどれも非常に安くて、¥200〜¥700くらいで、ちょっと普通の本屋にはおいてないようなマニアックな本が買えて、なかなか楽しかったです。2,3日目は行かないんだけど、プログラミング技術系の本とか、古いTVゲームに関するエッセイとか、あとはロックとか音楽系の本とか、そういうものがあれば欲しいかなーと思いました。今度は夏?かな。また行こうかな。

さいごに

ついでにと言ってはなんですが、2012年もいろいろお世話になりました。2012年統括的なブログを別途書くかどうかは未定。

2013年は、とりあえずアレをアレしなきゃなー。関係各所のみなさま、いろいろとお世話になりそうですが、どうかよろしくお願いします。

窓ぎわのトットちゃん

以前品川区の大崎というところに住んでいたんだが、自宅のとなりに「トット文化館」という障害者のための施設があった。「トット」ってなんだろうと妻に聞いたところ、黒柳徹子さんのあだ名であることがわかった。ふむーと思いつつ4年くらい大崎に住んで、いまは別のところに住んでます。

それでたまたま誰かのブログで「窓ぎわのトットちゃん」という本の話がでてて、そういえばまだ読んでないなーと思い、妻にたのんで図書館で借りてきてもらって読みました。

話の舞台となるトモエ学園、校長先生、そしてトットちゃん含め生徒全員がとても自然で優しくていい感じでした。

うちの娘もぜひこんな感じに育ってくれるといいな〜と。

窓ぎわのトットちゃん (講談社文庫)

窓ぎわのトットちゃん (講談社文庫)

 

 

解いてみた/ザッカーバーグの面接試験2:アクティビティ・インディケーター

ザッカーバーグの面接試験2:アクティビティ・インディケーター
http://satoshi.blogs.com/life/2012/08/zack2.html

こんな感じかな?

#import "NetworkActivityManager.h"

@implementation NetworkActivityManager

+ (id) sharedInstance {
    static NetworkActivityManager* manager;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[NetworkActivityManager alloc] init];
    });
    return manager;
}

- (id)retain {
    [super retain];
    if ([self retainCount] > 1) {
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    }
    return self;
}

- (oneway void)release {
    [super release];
    if ([self retainCount] <= 1) {
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    }
}

また、このケースで、シングルトンへのstrong referenceを使う利点と欠点を述べてください。

・利点:Reference countがインジケータのON/OFFスイッチの代わりにつかえてシンプルに書ける
・欠点:うーん、とくに思いつかない。関係ないところでは、上のコードはARC対象外になっちゃうので微妙ってくらいかなぁ。。

GCDとpthraedのコード比較

Grand Central Dispathでで並列プログラミングする場合に、条件変数(Condition Variable)を使いたい時はどうすればいいのかみたいな話を同僚としてたので調べてみた。結論としてはpthread_cond_xxxを使えばOK。

ところで私はpthreadもGCDもそんなに詳しくないので、学習がてら小さいコードを書いて両者を比較してみることにした。

pthreadで並列プログラミング

まずはGCDを使わずに、pthreadを使ってマルチスレッドなコードを実装。適当にpthreadでぐぐったら、codezine良い感じの記事とサンプルコードがあったので、これをベースにする(一部いじってある)

引用元:CodeZine「pthreadについて(条件変数・モデル)」
http://codezine.jp/article/detail/1894

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define THREAD_MAX 256

void* tmp_func(void* arg);

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER;

int start_flg = 0; //(2)pthread_cond_broadcast受け取り漏れ対策

int main(int argc, char** argv) {
    pthread_t pt[THREAD_MAX];
    int thr_count = 10;
    
    pthread_mutex_lock(&ready_mutex);
    for (int i = 0; i < thr_count; i++) {
        pthread_create(&pt[i], 0, tmp_func, &i);  //(1)indexの受け渡し対策
        pthread_cond_wait(&ready_cond, &ready_mutex);
    }
    pthread_mutex_unlock(&ready_mutex);
    
    sleep(1);
    
    start_flg = 1;
    fprintf(stdout, "pthread_cond_broadcast\n");
    pthread_cond_broadcast(&cond);
    for (i = 0; i < thr_count; i++) {
        pthread_join(pt[i], 0);
    }
    return 0;
}

void* tmp_func(void* arg) {
    pthread_mutex_lock(&ready_mutex); //(3)signal発行前に呼び出し元でwaitしていることを担保
    int index = *(int*)arg;
    pthread_cond_signal(&ready_cond);
    pthread_mutex_unlock(&ready_mutex);
    
    fprintf(stdout, "start thread index:[%d]\n", index);
    pthread_mutex_lock(&mutex);
    
    while (start_flg == 0) {
        pthread_cond_wait(&cond, &mutex);
    }

    pthread_mutex_unlock(&mutex);
    fprintf(stdout, "end thread index:[%d]\n", index);
    return 0;
}

このコードは以下の様なことをやっている。

  • 10個のスレッドを起動する
  • 各スレッドには起動時にindexが与えられる
  • 各スレッドは条件変数により待機状態になる
  • 全てのスレッドが起動しきったところで、待機しているスレッドを起こす
  • 全てのスレッドの実行が完了したらプログラム終了

これだけだが、そのままだといくつか問題があるので以下のように対処している。

  • (1)でスレッド側でiのポインタを渡す際に、呼び出し元でiの値を書き変えてしまわないように、条件変数ready_condを使ってガード
  • 最後に生成されるスレッドがwaitする前に、pthread_cond_broadcastされると、broadcastを受け取ることなくwaitしつづけるので、(2)のstart_flg変数でwaitするしないを制御
  • スレッド側で変数iを受けとってpthread_cond_signalを発行する際に、呼び出し元でwaitしていることを担保するために(3)でready_mutexをロック

ややこしいですねぇ。

GCDで並列プログラミング

上記プログラムを、GCDを使って書き換えた結果がこちら。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <dispatch/dispatch.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;

int start_flg = 0; //(c)

int main( int argc, char ** argv ) {
    int thr_count = 10;
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    
    for (int i = 0; i < thr_count; i ++ ) {
        dispatch_group_async(group, queue, ^{
            int  index = i; //(b)
            fprintf( stdout, "start thread index:[%d] input!!\n", index );
            pthread_mutex_lock( &mutex );
            while (start_flg == 0) {
                pthread_cond_wait( &cond, &mutex );  //(d)
            }
            pthread_mutex_unlock( &mutex ) ;
            fprintf( stdout, "end thread index:[%d] output!!\n", index );
        });
    }
    sleep( 1 );

    start_flg = 1;
    pthread_cond_broadcast( &cond );
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER); //(a)
    dispatch_release(group);
    return 0;
}

なんかだいぶスッキリした気がします。

ポイントは以下。

  • まずはblocksで無名関数がかけるのでスッキリ
  • joinのかわりにdispath_group_waitを使って、待ち合わせ処理がスッキリ (a)
  • 変数iの値は(b)の時点でblocksによってキャプチャされるので、iの受け渡しのために条件変数と同期変数を使う必要がなくなってスッキリ
  • start_flgが必要なのはかわらず(c)
  • GCDを使っていてもpthread_condやmutexは問題なく使用可能(d)

GCDとblocksによってかなりスッキリして良い感じです。GCDによってスレッドの制御も最適化されて性能的にも良さげです。

このへんの話は以下の資料、書籍も参考になります。

並列プログラミングガイド
https://developer.apple.com/jp/devcenter/ios/library/documentation/ConcurrencyProgrammingGuide.pdf

エキスパートObjective-Cプログラミング ― iOS/OS Xのメモリ管理とマルチスレッド
http://tatsu-zine.com/books/objc

怪しい点があればご指摘ください。

2012/07/01 21:01追記

  • start_flgやめてdispatch_semaphoreをカウントダウンラッチ的に使えばいいね

2011まとめ

仕事

1月

1月から新プロジェクトが立ち上がり、10月ごろまで掛け持ちで開発リーダーをやった。

3月

震災発生。地震発生時はエイプリルフール企画のMTGをやっていた真っ最中だった。ビルもすごい揺れた。地震発生直後からiPhoneでもNHKとかのサイマル放送をやることになったので、開発チーム総出で24H監視を行った。ちょっとは人様のお役に立てただろうか。

4月

スマホ関係の有料セミナーの講師をやった。

6月

元々やっていたほうプロジェクトの責任者になった。んで会長の別荘に行って作戦会議を行った。軽井沢の別荘は異世界だった。

8月

もう一方のプロジェクトで火事を起してしまった。8月はしんどかったな・・。反省。そして開発リーダーの掛け持ちは無理ってことがわかったので、そっちは別の方にお願いした。

10月

組織体制が変わって開発以外のこともよく見るようになった。売上とか売上とか。とはいえ11月〜12月は結構コード書いたな

全体

2010年以前にくらべて(色々ヘマもやらかしたが)より真面目に責任感を持って仕事に取り組めたような気がする。今の職場でも学ぶことはまだまだある気がする。

プライベートとか趣味とか

なんといっても5月に娘が生まれた。すごくかわいい。ありがとう妻〜ッ。
初めて病院から連れて帰ってきたときは、なんて小さくて儚い存在なんだ!と思ったが、7ヶ月目の今となっては存在感ありまくりで、元気に毎日、泣いたり、笑ったり、ウンチしたりしてます。
そういえば2011年の大晦日にはじめて喋った。何を喋っているかは不明だが「てんてん・・」みたいなことをつぶやいている。。

寄稿

仕事や子育てが忙しくなってきたので、2年半くらい続けてきた日経ソフトウエアへの寄稿を一旦終わらせてもらった。
かなり大変だったけど、よい経験となった。

Apple

iMacとMacBookAirとiPad2と、2011年もアップル製品をいろいろ買った
ジョブズが生きている間にWWDC行きたかった・・。合掌。

趣味の開発

どっちかと言えば、休日でも時間があまったら仕事のコードを書いてた。
ってことで2011年は、まとまった成果物はそれほどないな。
会社のハッカソンで作ったもの:http://www.kenmaz.net/html5/animemaker/

新しくはじめたこと

冬休みから、ふとした思いつきで電子工作を始めた。いつまで続くかな。
ドラムもよく練習していたけど、最近はやってないなー。

旅行

1月に石川県の実家&温泉、2月に箱根、9月にまた石川、って感じ。
娘が大きくなったらアメリカにでも行きたいな。

なわけで、今年もよろしく。

iOSアプリでプッシュ通知を完璧にテストする方法

もしかしたらよく知られていることなのかもしれないけど、割とハマったのでメモ。

iOSアプリでプッシュ通知機能のテストは結構面倒である。特に面倒なのが、アプリ初回起動時の挙動のテスト(以下の画像参照)。

iOSのプッシュ機能は以下のような流れで設定される。

  1. アプリ起動時にregisterForRemoteNotificationTypesメソッドを呼ぶ
  2. 端末はアップルのサーバー(APNs)と通信して、プッシュのためのデバイストークンを取得
  3. アプリの初回起動時にのみiOSが「<アプリ名>はあなたにプッシュ通知を送信します。よろしいですか?」というアラートを表示する
  4. 「はい」ボタンを押すと、APNsに端末が登録されプッシュを受信できるようになる

で面倒なのが、初回起動時のみに表示されるアラートのテスト。このアラートは本当に初回起動時にしか表示されず、アプリを一度削除して、再度インストールしても、このアラートは二度と表示されない。

が、以下の手順を踏めば、再度アラートを表示させることができる。

  1. アプリを削除する
  2. Macのシステム時計を2週間ほど早める(!)
  3. iPhoneを再起動する
  4. iPhoneをMacに接続すると、iPhoneのシステム時計が2週間進む
  5. アプリを再インストールする
  6. アラートが表示される

iPhoneの設定で直接時刻すると、Macに接続した瞬間に時間が補正されてしまって元に戻ってしまうので、仕方なくMac側のシステム時計を変更している。

ちなみにiPhoneのシステム時計をあんまり進めすぎるとプロビジョニングプロファイルの有効期限を超えちゃって実機転送できなくなるのでお気をつけて。

詳しくは以下を参照してくださいー。
http://developer.apple.com/library/ios/#technotes/tn2265/_index.html

Resetting the Push Notifications Permissions Alert on iOS
The first time a push-enabled app registers for push notifications, iOS asks the user if they wish to receive notifications for that app. Once the user has responded to this alert it is not presented again unless the device is restored or the app has been uninstalled for at least a day.

If you want to simulate a first-time run of your app, you can leave the app uninstalled for a day. You can achieve the latter without actually waiting a day by setting the system clock forward a day or more, turning the device off completely, then turning the device back on.

娘のスキル一覧

生まれてから2ヶ月が経過し、横顔が父親に似てきた娘だが、ここで一旦彼女がこれまでに習得したスキルを整理してみる。

  • 生後1ヶ月までに習得したスキル
    • 寝る
    • 起きる
    • おしっことうんちをする
    • 乳を吸う
    • ときどき吐く
    • 泣く
    • へっへっ、あ〜、う〜、う”〜、などと発声する
    • 何かを見つめる
  • 生後2ヶ月までに習得したスキル
    • 拳をしゃぶる [New!]

あと6年くらいしたら「FizzBuzz問題を解ける」くらいに成長してるといいな!