Xcode6でのNSUserDefaultsの保存場所

Xcodd6でiPhoneシミュレータでNSUserDefaultsを使った場合に、XXX.plistの保存場所がこれまでと違うところになっていました。

新しい保存場所

~/Library/Developer/CoreSimulator/Devices/
4F7008B7-994C-497F-81DF-BBE23011A436/data/Library/Preferences/
<Bundle Identifier>.plist

のような感じです(見やすいように改行しましたが、ほんとは1行です)。4F700…はデバイスID、はプロジェクトのTARGET、Identityに表示されるBundle Idetifierですね。

ドキュメントは

~/Library/Developer/CoreSimulator/Devices/
58029C13-C203-4155-B2B1-0BF46820347B/data/Containers/
Data/Application/5AB20983-88BA-42C8-A57F-1C01BDA7B9CB/Documents

なんだか長いですね。こちらも見やすいように改行しています。
58029C23…はデバイスID、5AB20983-…は何でしたっけ?

unrecognized selector sent to instance 0x…

エラーでXcodeでの実行が止まってしまいました。

どうやら存在しないオブジェクトに何か使用としている感じです。削除したにも関わらず、それを知らないでメソッドを使おうとしているようです。

よくよくみたら

  [[NSNotificationCenter defaultCenter] postNotification:n];

のところで例外が発生してました。

Thread 1: EXC_BAD_ACCESS (code=1, address=0x….)

ようするに
1. オブジェクトが通知センターに登録していた。
2. 役割が終わってオブジェクトを削除した。
3. 通知の登録は残ったままだから、通知を送ろうとしたら相手がくて例外が発生。
となってしまいました。

ということで、通知センターに登録した場合は、不要になったらきちんと登録を解除しましょう。

[[NSNotificationCenter defaultCenter] removeObserver:取り除くオブジェクト];

XcodeのPBXCp Error

Xcodeのプロジェクトがあるフォルダから、使ってないファイルを取り除いてビルドしたらこのエラーが出てきました。

error: /Users/(…パス…)/取り除いたファイル名: No such file or directory

プロジェクトを選択して、Build Phases => Copy Bundle Resources
から赤くなっているファイルを選択して、下の「-」ボタンで削除。

こちらの手順をそのまま使わせていただきました。

iOSでロケールを判断する

iOSでロケールを取得して判断するには

NSArray *langs = [NSLocale preferredLanguages];
if ([langs[0] isEqualToString:@"ja"]) {
   日本語の場合の処理
} else {
   その他のロケールの処理
}

のように条件分岐します。簡単と言えば簡単ですが、判断するロケールが増えると面倒ですね。

Inconpatible integer to pointer conversion assigning to …

Xcodeを使っていて

Inconpatible integer to pointer conversion assigning to 'int *' from 'int'

というワーニングが出てしまいました。

理由は

@property int *xxx;
…
self.xxx = 3;

のようにポインタに数値を入れてしまったためです。

くだらいない間違いですが、「@property」で始めると、私は何も考えず「*」を付けてしまうことがあるようです。気をつけなきゃ。

delegateの書き方

Objective-Cでdelegateを使うときのメモです。
「delegateとは」といった説明は何にもありません。単に書き方だけです。

delegateの呼び出し側(「XXX」とする)

// XXX.h
@protocol xxxDelegate
-(void)foo;
@end

@interface XXX : スーパークラス名
@property (retain, nonatomic) id <xxxDelegate> delegate;
@end
// XXX.m
@synthesize delegate;

// 呼び出す場所で
[delegate foo];

呼び出される側(「YYY」とする)

// YYY.h
#import "XXX.h"
@interface YYY: スーパークラス名 <xxxDelegate>

// delegateメソッドを宣言
-(void)foo;
// YYY.m

XXX *xxx;             // インスタンスを作って
xxx.delegate = self;  // 自分を呼び出すようにしておく

// 実装
- (void)foo
{
…
}

NSUserDefaultの読み書き

NSUserDefaultsで保存、読み込むときのまとめです。

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 辞書オブジェクトとして保存
[defaults setObject:辞書オブジェクト forKey:@"キー名"];
// 文字列オブジェクトとして保存
[defaults setObject:文字列オブジェクト forKey:@"キー名"];
// ブール値として保存
[defaults setBool:ブール値 forKey:@"キー名"];
[defaults synchronize];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 辞書を読み込む場合
NSDictionary *dic = [defaults objectForKey:@"キー名"];
// 文字列を読み込む場合
NString *str = [defaults stringForKey@"キー名"]; 
// ブール値を読み込む場合
BOOL bool = [defaults boolForKey@"キー名"];

CoreGraphicsで画像を回転させる

画像を回転させる手順です。以前、座標軸も回転することが分からず時間を費やしてしまいました。

(0) 元の画像

(1) 画像の左下を、中心まで移動する。

(2) 回転させる。
回転は、左下を軸として行われます。このとき座標軸も回転しています。

(3) 高さを戻す。

(4) 幅を戻す。

これで結果的に画像の中心を軸に回転した画像になりました。

// (1)
CGContextTranslateCTM(ctx, width/2, height/2);
// (2)
CGContextRotateCTM(ctx, angle);
// (3)
CGContextTranslateCTM(ctx, 0, -height/2);
// (4)
CGContextTranslateCTM(ctx, -width/2, 0);

0307