24/7 twenty-four seven

iOS/OS X application programing topics.

NSDictionary の objectForKey: と valueForKey: の違い

objectForKey: は NSDictionary のメソッドですが、 valueForKey: は KVC (Key Value-Coding) 由来のメソッドです。

If key does not start with “@”, invokes objectForKey:. If key does start with “@”, strips the “@” and invokes [super valueForKey:] with the rest of the key.

NSDictionary Class Reference

上記の通り、たいていの場合 valueForKey: は objectForKey: と同じ結果を返しますが、キー値が「@」から始まる場合、異なる動作をします。
キー値が「@」から始まる場合、「@」を除いた値を引数にしてスーパークラスの valueForKey: を呼び出すとあるので、NSObject の valueForKey: が呼ばれることになります。
つまり、KVC のキー値によるプロパティのアクセスになるので、偶然同じ名前のプロパティかメソッドを持っていない限り、例外が発生してクラッシュします。
たとえ同じ名前のメソッドを持っていてクラッシュを免れたとしても期待する動作ではないでしょう。

下記のようにキー値に何を渡しているか間違いない場合は構いませんが、キーに変数を渡す場合などはもしかしたら「@」で始まる値が入ってくるかもしれません。

NSString *name = [dictionary valueForKey:@"name"]; // OK
NSString *name = [dictionary valueForKey:nameKey]; // 危険


ということで、NSDictionary から値を取得する場合は、いつでも objectForKey: を使う方が安全です。

Objective-C における可変引数の実装方法

Q: How can I write a method that takes a variable number of arguments, like NSString's +stringWithFormat:?
A: Methods that take variable arguments are known as variadic methods.

Keep in mind that the implementation of an Objective-C method is just a block of code, like a C function. The variadic argument macros described in the stdarg(3) manual page work the same way in a method as they do in an ordinary function.

Mac Developer Library
#import <Cocoa/Cocoa.h>

@interface NSMutableArray (variadicMethodExample)

- (void) appendObjects:(id) firstObject, ...;  // This method takes a nil-terminated list of objects.

@end

@implementation NSMutableArray (variadicMethodExample)

- (void) appendObjects:(id) firstObject, ...
{
id eachObject;
va_list argumentList;
if (firstObject)                      // The first argument isn't part of the varargs list,
  {                                   // so we'll handle it separately.
  [self addObject: firstObject];
  va_start(argumentList, firstObject);          // Start scanning for arguments after firstObject.
  while (eachObject = va_arg(argumentList, id)) // As many times as we can get an argument of type "id"
    [self addObject: eachObject];               // that isn't nil, add it to self's contents.
  va_end(argumentList);
  }
}

@end

二重解放 (double free) や 解放済みオブジェクトへのアクセス (EXC_BAD_ACCESS) によるクラッシュを Instruments を使って調べる

iPhone アプリケーションのプログラミングでは、メモリ管理に注意する必要があります。
特に解放済みのオブジェクトをさらに解放してしまったり(二重解放)、解放済みのオブジェクトを操作しようとした場合は即座にアプリがクラッシュしてしまいます。


このようなメモリ関連のバグによるクラッシュの場合、何も残さずに突然終了してしまうことが多いため、原因の究明が困難です。


そんなメモリ管理のバグを Instruments を使って少し簡単に調査する方法を紹介します。
残念ながら、シミュレータでしが機能しないのですが、それでも原因の解明が簡単になる場合が結構あります。


下記のサイトでは、動画と画像でさらに詳しく解説されているので、そちらも参考にしてください。
iPhone Memory Debugging with NSZombie and Instruments — markj.net

プロジェクトをビルドして、「実行」>「パフォーマンスツールを使って実行」>「Object Allocations」を選択します。

Instruments の設定を変更するため、「Stop」を押して、いったん停止します。

「ObjectAlloc」の右側にある「i」マークのボタンを押して「Record reference counts」と「Enable NSZombie detection」を有効にします。

「Record reference counts」はオブジェクトごとの参照カウンタの記録、「Enable NSZombie detection」は dealloc されたオブジェクトを実際には解放せずに、ゾンビオブジェクトとして扱う機能になります。
実際にはオブジェクトを解放しないので、クラッシュ時に原因の追跡が可能になります。

設定を有効にしたら、「Record」ボタンを押してアプリケーションを再実行します。

アプリケーションを操作してクラッシュを再現します。
すると、(メモリ関連のバグの場合)下記のように Instruments にクラッシュが報告されます。

ここで吹き出しの右下にある矢印ボタンを押すと、原因となったオブジェクトの状態の経過と、参照カウンタが表示されます。

さらに、該当する行が自分で書いたコードの場合、行をダブルクリックすることで、コードの表示にジャンプします。


以上です。
コードが大きくなってくると、メモリ関連の異常終了はなかなか原因を特定することが難しいですが、上記の方法にてデバッグすることで少し簡単になることがあると思います。

iTunes の購入用パスワードが保存されない問題を直す

Fix for iTunes 9.0.1 refusing to save your store password - CNET
iTunes repeatedly prompts to authorize computer to play iTunes Store purchases


次のうちどちらかを実行すると直るようです。
私の場合は1の方法で今のところ問題は再発していません。

  1. 「コンピュータの認証を解除」後、iTunes を再起動して再度認証する
  2. Apple アカウント情報の画面から「警告のリセット」を実行する

「コンピュータの認証を解除」後、iTunes を再起動して再度認証する

  1. Store > コンピュータの認証を解除...
  2. iTunes を再起動
  3. Store > コンピュータを認証...

Option 1:
Launch iTunes
Go to Store Menu > Deauthorize Computer
Once deauthorization is complete, quit iTunes
Relaunch iTunes
Go to Store Menu > Authorize Computer

Fix for iTunes 9.0.1 refusing to save your store password - CNET

Apple アカウント情報の画面から「警告のリセット」を実行する

  1. Store > マイアカウントを表示...
  2. 「警告のリセット」ボタンを押す

Option 2:
Launch iTunes
Go to Store Menu > View My Account(your Apple ID)
Click Reset Warnings

Fix for iTunes 9.0.1 refusing to save your store password - CNET

スポイトツールで拾った色を簡単にコードに変換できるDeveloper Color Picker

Developer Color Picker

A custom color picker designed specifically for developers. Makes getting colors out of Photoshop/Acorn mock-ups quick and easy. Currently supports NSColor, UIColor, CGColorRef, CSS and HTML styles.

Developer Color Picker

Copy ボタン、または Copy with Declaration ボタンを押すと下記のようにコードの形でクリップボードにコピーされます。

NSColor *aColor = [NSColor colorWithCalibratedRed:0.488 green:0.585 blue:0.397 alpha:1.000];
UIColor *aColor = [UIColor colorWithRed:0.488 green:0.585 blue:0.397 alpha:1.000];
CGColorRef aColor = CGColorCreateGenericRGB(0.488, 0.585, 0.397, 1.000);

Objectibe-C 以外に、HTML の Hex Color や CSS の形式に対応しています。

インストールは、ファイルを展開して ~/Library/ColorPickers にコピーします。
ColorPickers ディレクトリが存在しない場合は新しく作成します。

ディスクに存在するXcodeプロジェクトのビルドディレクトリを自動的に削除してくれるアプリケーション

BuildCleaner
A simple app that searches for old and unused Xcode build folders and deletes them. A couple options are available, including the ability to ignore build folders for specific projects and the cutoff interval for deleting folders.

http://www.davedelong.com/downloads


起動するとメニューバーに常駐します。

削除処理の周期が設定できます。

実行してみると、私の環境では約1GB削除されました。


ダウンロードはこちらから。
http://www.davedelong.com/downloads

Bento 2ファーストインプレッション

さっそくインストールして触ってみました。
とりあえずビデオチュートリアルを見て研究です。
http://www.filemaker.co.jp/products/bento/tours_tutorials


チュートリアルを見て感じた印象は、

  • データベースだけど型の概念がゆるい(表計算ソフトのよう)
  • Keynoteのように見栄えの良い画面を作るのが簡単
    • ドラッグ時にガイドに吸い付く
    • 余白に自然に広がってくれる、など
  • フォーム画面と表画面を行き来して操作する

といったところです。
思っていたよりも強力でしかも簡単に使えそうだと思いました。


また、アドレスブック、iCalとの連携が秀逸です。
最初からアドレスブックの内容がBento 2に取り込まれて表示されています。
そしてBento 2で入力した内容がすぐにアドレスブックに反映されます。
たぶん同じファイルを参照してるのでしょうか。

標準のアドレスブックの入力は使いにくいので、メンテナンスが面倒になりがちなのですが、Bento 2の表画面から入力すると非常に簡単です。
前の携帯電話から取り込んだために、ふりがなが半角カナだったり、姓のところに名前まで入ってしまったりと、統一がとれていなかったのですが、それを一気に直すことができました。

とりあえず、アドレスブック編集ソフトとして、それだけでかなり使えます。

パーソナルデータベース「Bento 2」体験モニターに当選しました。

http://www.filemaker.co.jp/products/bento/overview.html
「Bento 2 体験モニター」プロジェクト

Mac Fanで募集していた、個人向けデータベースソフト「Bento 2」の体験モニターになりました。
これからちょくちょく「Bento 2」のレビューを書いていこうと思います。


Xcodeで自動生成されるコメントの__MyCompanyName__を変更する。

~/Library/Preferences/com.apple.Xcode.plistを編集します。

$ defaults write com.apple.Xcode PBXCustomTemplateMacroDefinitions \
'{FULLUSERNAME="KISHIKAWA Katsumi"; ORGANIZATIONNAME="KISHIKAWA Katsumi";}'


//
//  AppDelegate.h
//  UICCalendarPicker
//
//  Created by KISHIKAWA Katsumi on 09/01/01.
//  Copyright 2009 KISHIKAWA Katsumi. All rights reserved.
//

クラスリファレンスはXcode製品ドキュメントで

紙で欲しい。
DevCenter のような冗長なのじゃなくて、パッとチェックできるようなやつが欲しい。
特に NSString と NSArray がいい。

2008-09-07 - iOS プログラミングメモ - iPhoneアプリ開発グループ

Xcodeのヘルプ>製品ドキュメントを開くと、リファレンスがダウンロードできます。

一度ダウンロードすると、いつでも見られます。
Dev Centerにログインしなくていいので快適です。Dev Centerはすぐにセッションが切れちゃいますしね。

また、インクリメント検索ができて非常に速いので、メソッドから調べたいとか、URL関係のクラスは何があるか知りたい、なんてときも便利に使えます。

"MDCrashReportTool"は、予期しない理由で終了しました。

昨日あたりから、iPhoneを同期するたびに、上記のようなメッセージが出るようになった。
最初は、バックグラウンドで動いてる何かの動作がおかしくなったのだと思っていたが、再起動してすぐのときも出たので、調べてみた.

I made this stop by using iTunes to Restore the iPhone. Takes a long time (like, half an hour), but it does restore all your settings as well as the software. I suspect this will only be a temporary fix, though.

There are reports that you can make this stop by removing or renaming MDCrashReportTool. On OS X, it's at
/System/Library/PrivateFrameworks/MobileDevice.framework/Resources/AppleMobileDeviceHelper.app/Contents/Resources/MDCrashReportTool

On windows, see http://discussions.apple.com/thread....76735&tstart=0

These strike me as hazardous, as updaters might not like your messing about where you're not welcome.

What I think I've learned from all this: Looks like
1. when an app crashes in the iPhone (I've had several), something is recorded there
2. next sync, the crash record is uploaded to the host (Mac or PC)
3. if you chose to do so during installation, this is sent to Apple for their bug-fixing pleasure
4. this would be handled by this MDCrashReportTool thing
5. but there's a bug in that

Resetting the iPhone, I suspect, cleared the record of old crashes, but the next time I have an app crash, it'll start all over again.

MDCrashReportTool Crash??? - MacRumors Forums

つまり、MDCrashReportToolというのは、iPhoneのアプリケーションがクラッシュしたときのレポートを自動的にMacに転送するプログラム、らしい。
それにバグがあると。
iPhoneを復元したら直るけど、1時間くらいかかるし、再発するかもしれない。
もしくはMDCrashReportToolの名前を変えるか消すかする。でもアップデートのときに困るかも。


うーん、復元は面倒だし、またすぐ再発しそうなんで、しばらく気にしないでほっとくことにします。

VirtualBox 1.6のハードディスクイメージ(VDIファイル)はプラットフォーム間の互換性が無い?

先日リリースされたVirtualBox 1.6のMac OS X版を少し使ってみる。
メニューや設定項目、画面の作りはUbuntu版と全く同様。メニュー項目に小さいアイコンが付いてるところまで同じ。Macっぽくなくてカッコ悪いからやめてほしいのだが。

とりあえず、Ubunntu版で使ってるCent OS 5の仮想環境のハードディスクイメージをコピーして使うことにする。
しかし、カーネルが起動しない。途中で固まってしまう。


そこで試しに別の環境、Windows XPが入ったイメージをコピーして起動してみる。
今度はBIOSの起動画面の直後にブルースクリーンが出た。
どうも異機種間でイメージファイルを共用することはできないようだ。


明日は普通にインストールしてみることにする。
ついでに逆方向のコピー(Mac→Ubuntu)も試してみよう。

VirtualBox 1.6リリース

VirtualBox 1.6(Sun xVM版)リリース、Mac OS Xに正式対応

Ubuntuにインストール済みのVirtualBox 1.5.6をアップデート

ダウンロードページからBinaries (all platforms)をクリック。

「Platform: Ubuntu 8.04 x86」を選択。

ダウンロードした「virtualbox_1.6.0-30421_Ubuntu_hardy_i386.deb」をダブルクリックし、「パッケージのインストール」クリックしてインストール。
このとき、もともと入っていたオープンソース版を削除しないとインストールできなかった。
「virtualbox-ose」と「virtualbox-ose-modules-2.6.24-16-generic」を「Synaptic パッケージ・マネージャ」から削除する。

起動すると設定ファイルを更新するかどうかというダイアログが出る。このとき、古い設定をバックアップすることも選べる。

バーチャルマシンごとの設定画面を眺めてみる。
「USB 2.0コントローラを有効にする」オプションが追加されている。とりあえずチェックしてみる。

それ以外は大きな変更はないみたいだ。

バーチャルマシンを起動すると、起動時のロゴがSunのものに変更されている。

動作は以前のバージョンとほとんど変わらない。USB 2.0のサポートも速いのかどうか分からなかった。前のバージョンではいきなり終了してしまうことがあったが、安定性が向上しているかどうか、これから確かめていこうと思う。

Mac OS X

Mac OS X (Intel)をダウンロード。
普通にdmgファイルなのに拡張子がなぜか.dmg.bz2になってしまったので.dmgに直す。
とりあえず今日はインストールのみ。
VMWare Fusionを持ってるので乗り換えるかは微妙だが、試してみることにする。