viewDidUnload はメモリ不足時だけに呼ばれる

先日、instruments でリークを発見した際にあまりにも恥ずかしい勘違いがあったので、メモしておきます。
viewDidUnload は、メモリ不足警告時においてのみ呼び出される。ということ。

何気なく、- (id)init でアロケートし、- (void)dealloc で解放してましたが、理解不足でした。
よく覚えておこう。

NSCalendar : 月末が第何週目か取得する方法

NSCalendar クラスの ordinalityOfUnit:inUnit:forDate:メソッドが便利だったのでメモしておきます。
例えば、月末が月の第何周であるか?とか調べるのに利用できます。
その他、年内で第何周であるか?とかも調べられるはず。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// NSDate にカテゴリでメソッドを追加しておく
@interface NSDate (DateAdditions)
 
// 月の日数を取得する
- (NSUInteger)getNumberOfDaysInMonth
{
    return [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:self].length;
}
 
		:
		:
// 月の日数を取得する
NSDate *todayDate = [NSDate date];
NSUInteger lastdayInMonth = [todayDate getNumberOfDaysInMonth];
 
// 本日日付を年月日で分解する
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *dateComps = [cal components:NSYearCalendarUnit | 
                                              NSMonthCalendarUnit |
                                              NSDayCalendarUnit
                                     fromDate:[NSDate date]];
// 月末日付を取得する
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:dateComps.year];
[comps setMonth:dateComps.month];
[comps setDay:lastdayInMonth];
NSDate *lastDate = [cal dateFromComponents:comps];
[comps release];
 
// 月末が第何週目か取得する
NSUInteger lastdayWeekNo = [cal ordinalityOfUnit:NSWeekCalendarUnit 
                                          inUnit:NSMonthCalendarUnit 
                                         forDate:lastDate];
// 本日が月の第何週目か取得する
NSUInteger todayWeekNo = [cal ordinalityOfUnit:NSWeekCalendarUnit 
                                        inUnit:NSMonthCalendarUnit 
                                       forDate:[NSDate date]];

xcode4.3をインストール

本日はまたいろいろ Apple 関連のニュース(OS X Mountain Lion とか)があったが、xcode がバージョンアップしたとのことだったので、早速インストールした。
インストール作業は滞りなく進んだが、xcode4.3を起動することができず、少し悩んだ。
xcode4.3 は アプリケーション フォルダにインストールされるらしい。

また、こんなメニュー項目も追加されているみたい。

キーボードに入力領域が重ならないようにする方法

以下の様なテーブル ビューをデザインしたとします。
テーブルのセルにはテキスト フィールドが配置されており、キーボードからの入力が可能とします。

ボタン10のタイトル行などにキーボード入力を行おうとフォーカスを移動すると、画面下部から表示されるキーボードで入力領域が隠されてしまうことになります。

そこで入力領域が重ならないように、以下の様にテーブルを引っ張り上げます。(表現がいまいちですが、通常のスクロールでは移動できない位置にセルを上げ下げします。)
このような表示は、キーボードの表示、非表示時に UITableView の UIEdgeInsets の値を調整することで、編集中セルを画面中央へ移動させることが可能です。
あと、iOS 5 では、日本語キーボードの上部に予測変換候補が表示される仕様となっているようなので考慮しておきます。

手順は、以下の通り
1. UITableViewController でキーボードの通知を取得できるようにする
2. キーボードの表示、非表示に UITableView の UIEdgeInsets の値を調整することで、編集中セルを画面中央へ移動させる

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
 
        // ソフトキーボードの表示、非表示の通知を登録する
        NSNotificationCenter *center;
        center = [NSNotificationCenter defaultCenter];
        [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [center addObserver:self selector:@selector(keybaordWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }
 
    return self;
}
 
- (void)dealloc
{
    // ソフトキーボードの表示、非表示の通知を解除する
    NSNotificationCenter *center;
    center = [NSNotificationCenter defaultCenter];
    [center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
 
    [super dealloc];
}
 
#pragma mark -
#pragma mark Software Keyboard Mthods
 
- (void)keyboardWillShow:(NSNotification*)notification
{
    NSDictionary *userInfo;
    userInfo = [notification userInfo];
 
    // 1. キーボードの top を取得する
    CGRect keyboardFrame;
    keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
 
    CGFloat keyboardTop = (APP_CONTENT_HEIGHT) - (keyboardFrame.size.height + 55.f );   // 55.f:予測変換領域の高さ
 
 
    // 2. 編集中セルの bottom を取得する
    // テーブル ビューはスクロールしていることがあるので、オフセットを考慮すること
    UITableViewCell *cell;
    cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath_.row 
                                                                    inSection:indexPath_.section]];
    CGRect cellFrame;
    cellFrame = cell.frame;
 
    CGPoint offset = CGPointZero;
    offset =  self.tableView.contentOffset;  
 
    CGRect cellRectOrigin = CGRectZero;    
    cellRectOrigin.origin.x = cellFrame.origin.x - offset.x;  
    cellRectOrigin.origin.y = cellFrame.origin.y - offset.y; 
 
    CGFloat cellBottom = cellRectOrigin.origin.y + cellFrame.size.height + 30.f;   // 30.f:マージン
 
 
    // 編集中セルの bottom がキーボードの top より上にある場合、
    // キーボードに隠れないよう位置を調整する処理対象外とする
    if (cellBottom < keyboardTop) {
        return;
    }
 
 
    // 3. 編集中セルとキーボードが重なる場合、編集中セルを画面中央へ移動させる
    // キーボードの高さ分の insets を作成する    
    UIEdgeInsets insets;
    insets = UIEdgeInsetsMake(0.0f, 0.0f, keyboardTop, 0.0f);
 
    NSTimeInterval duration;
    UIViewAnimationCurve animationCurve;
    void (^animations)(void);
    duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
    animations = ^(void) {
        self.tableView.contentInset = insets;
        self.tableView.scrollIndicatorInsets = insets;
    };
    [UIView animateWithDuration:duration delay:0.0 options:(animationCurve << 16) animations:animations completion:nil];
 
    // 編集中セルの位置を調整する
    CGRect rect = cell.frame;
    rect.origin.y = cellFrame.origin.y - 300.f;
 
    [self.tableView scrollRectToVisible:rect animated:YES];
}
 
- (void)keybaordWillHide:(NSNotification*)notification
{
    NSDictionary *userInfo;
    userInfo = [notification userInfo];
 
    NSTimeInterval duration;
    UIViewAnimationCurve animationCurve;
    void (^animations)(void);
    duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
    animations = ^(void) {
        // insets を 0 にする
        self.tableView.contentInset = UIEdgeInsetsZero;
        self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero;
    };
    [UIView animateWithDuration:duration delay:0.0 options:(animationCurve << 16) animations:animations completion:nil];  
}

xcode の git ステータスが表示されなくなった際の対処方法

xcode4 で開発を行っている際に git を利用しているとプロジェクト ナビゲータのファイル横に改変ステータスが表示されます。
例えば、追加されたファイルには”A”、編集されたファイルには”M”などのマークです。

これらのマークがある時期から表示されなくなったので何とか表示したいと考えていたのですが、対処方法を調べる時間がなく、そのままの状態で開発を行っていました。
ですが、改版中のファイルが分かるとあとでコードの見直しなどする際にメリットがあるので、少し調べてみました。

私の環境でそのような現象が起きていたのは、作業開始時に開発に関するファイルをコピーしてから作業を開始している為のようです。その際、git の管理ができなくなっており、新規に作成したファイルなどの改変ステータスが表示できなくなっているようです。

というわけで、コマンドラインから新規作成ファイルをプロジェクトにインポートすることで git の管理下に置くことで、プロジェクト ナビゲータの改変ステータスが表示されるようになるか確認したところ、正常に改変ステータスを表示できるようになりました。
その際のコマンドは以下の通り。

git に新しいプロジェクト ソースをインポートする方法を参考に対処することにした。

$ cd (プロジェクトのトップディレクトリ)
$ git init
$ git add .
$ git commit -m "コミット コメント"

参考になるURL
チュートリアル:新規リポジトリのインポート

Git ユーザマニュアル:新規リポジトリの作成

「WEB+DB PRESS vol.50 はじめてのGit」にも git 記事があるようです。

カスペルスキー アンチウイルス2011 for mac インストール

以前より osx でのウイルス対策として”カスペルスキー”を利用している。
今月ライセンスが切れたので、新たに更新した。
カスペルスキーは、2011年まで日本国内ではジャストシステムが販売していたが、2012年からはカスペルスキーが販売しているようだ。そのため、アクティベーション時に入力する新しいコードが古いアプリでは認識できないようで、一度アプリをアンインストールする必要がある。

アンインストール方法は、アプリ dmg のアンインストール プログラムを利用する。

また、以前のカスペルスキー(8.0.1.xxx)を利用していて “Time Machine がバックアップに失敗する” という問題が起きていたので新しいカスペルスキーをインストールした際に以下の設定を行い対処しておいた。

私の環境では、Time Machine と以前のカスペルスキーを併用していた場合、新規にバックアップを取得し始めてから1ヶ月程で Time Machine が定期バックアップに失敗し、新たに新規バックアップを作成し直さなければならないという現象が起きていた。だが、以下の設定をカスペルスキーに行ってからは、約一年ほど運用していて、Time Machine がバックアップに失敗する現象が再現していないので、有効だと判断している。

・環境設定 – プロテクション – スキャン範囲
“すべてのネットワークドライブ”を除外した

・環境設定 – 除外設定
Time Machine.app を脅威から除外した

macbook air ’11 開封の儀

先日ポチッたブツが届きましたので、早速、開封の儀です。

年末年始からアップルストアや電気店で実際に触ってみて吟味した結果、11インチにすることにしました。
11インチ、13インチどちらもよくできており大変悩みましたが、すでにメインマシンには27インチがありますし、現在利用している macbook(ポリカーボネイト白)のリプレースなので、モバイル用途としてのメリットを最大限に生かすため11インチにしました。
ポリカーボネイトは、2Kgオーバーだったので、半分の重さになりました。(^^)v

あと、決め手は 11インチといえどキーボードが扱いやすいところです。
約10年前にも某社の10.?インチ ノートPCを利用していたことがありますが、サブノートというようなカテゴリーのマシンはキーボードが扱いづらく苦労した思いがあります。

では、簡単に開封の儀で macbook air ’11をご紹介です。(^^)


すごくパッケージが小さいです。そしてとても軽いです。
なんかプラモデルの箱のような感じです。

いいですね。ご対面です。
過去、2台ほど国産ノートPCを購入したことがありますが、このタイプのパッケージではありませんでした。アップル製品のような箱を開けるとご対面って形は、珍しいんじゃないでしょうか?
箱の横に二重のふたがあって、本体を引っ張り出すような形状のパッケージでしたが、ご対面の感動がないんですよね。


ここで一つ心配事が浮かびました。
Ethernetアダプタも同時に購入していたのに見当たりません。
環境のセットアップ後、TimeMachineでバックアップしようと考えていたので、ショックです。(T-T)
無線での初回バックアップは避けたいですよね。。。。って少しテンションが下がりましたが。。。あっありました。(笑)
この演出、さすがアップルさんです。って違うか。
余計な梱包物もなく、すてきです。

早速、電源オンです。
しらばらくすると、なんかマシンが日本語の音声でも案内をしてくれます。
すてきやん!分かりやすいやん!

ひとしきり感動した最後に、下の画面です。
何気なくマルチタッチ ジェスチャをユーザに理解させる演出。

“Mac OS X Lion を始める”ボタンが出てきました。さりげなさに感動。
いい作品に出会いました。