ページ

2010年6月13日日曜日

サイトをリニューアルしました

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

新しいサイトはこちらです↓

Cocoaの日々

※このサイトは閉鎖せずに今後も公開しておきます。

長い間ありがとうございました。
よければ新しいサイトの方も訪問してみて下さい。

橋口

2010年6月12日土曜日

CoreData - トランザクション(5) まとめ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

前回までの検証結果まとめ。

NSManagedObjectContext操作まとめ

操作説明ディスク操作Undo/Redoの履歴
save現時点でのメモリの内容を保存する書き出しなし
rollbackディスク上の内容に戻す(必要なら)読み込みクリア
undo1つ前の操作を取り消す(操作直前の内容に戻す)なしなし
redo次の操作をもう一回行う(取り消した操作を復活)なしなし
resetメモリの初期化(変更の破棄、読み込まれたオブジェクトの破棄)なしクリア

(参考)NSManagedObjectContext Class Reference - Undo Management

今まで検証に使ったソースは GitHub からダウンロードできる。
CoreDataTransaction at 2010-06-12 from xcatsan's SampleCode - GitHub

2010年6月11日金曜日

CoreData - トランザクション(4) reset

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

-[NSManagedObjectContext reset] を試す。

コードを追加し、

- (IBAction)resetAction:sender
{
[self.managedObjectContext reset];
}

ボタンに紐づける。
実行。resetボタンを押すと、
データが消える。
これは NSManagedObjectContext(メモリ)上のデータが消えただけで、ディスク上のデータは残っている。

試しに reload ボタンを追加する。
ボタンが押されたら、NSArrayController を使っているので prepareContent を投げてみる。

- (IBAction)reloadAction:sender
{
[arrayController prepareContent];
}


すると reset で一旦消えた後、
reloadボタンで復活。

reset するとそれまでに読み込まれた NSManagedObject がすべて開放される(ドキュメントでは "forgotton" という表記)。当然ながら直前の変更状態はディスクには残らず破棄されてしまう。Undo/Redo履歴もクリア。用途としては NSMangedObjectContext のインスタンスを別の用途で使いまわす場合の初期化に使うことが考えられる。

2010年6月10日木曜日

CoreData - トランザクション(3) undo と redo

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

undo と redo をやってみる。

まずアクションメソッドを用意する。

- (IBAction)undoAction:sender
{
[self.managedObjectContext undo];
}
- (IBAction)redoAction:sender
{
[self.managedObjectContext redo];
}


Interface Builder を開き、Undo/Redoのボタンを追加する。これを先程のメソッドに紐づける。
実行する。確かに Undo/Redo が効いている。なお標準でメニューのUndo/Redoが FirstResponderにひもづけられており、実は今回のボタンを用意しなくてもメニューから Undo/Redoが行えた。

save と rollback の関係だが次のようになっていた。
(1) save後、Undo/Redo操作 は行える
(2) rollback後、Undo/Redo操作は行えない(操作履歴がクリアされる)

2010年6月9日水曜日

CoreData - トランザクション(2) rollback

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

rollback を試してみよう。前回のサンプルに Rollback ボタンを追加する。

rollback用のアクションコードを書き、そこへ紐づける。

- (IBAction)rollbackAction:(id)sender
{
[self.managedObjectContext rollback];
}


実行してみよう。
新規にレコードを追加し、入力したところで Rollback ボタンを押す。
すると新規レコードが取り消されるのがわかる。


複数の操作も試してみよう。
まず新規レコードを追加し
元からあったレコードを修正し
1レコード削除する
そして Rollback
元に戻った。

2010年6月8日火曜日

CoreData - トランザクション(1) 準備

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

CoreData のトランザクションについて調べてみる。

NSManagedObjectContext では Undo Management としていくつかメソッドが用意されている。
NSManagedObjectContext Class Reference - Undo Management

これらの挙動を試す簡単なサンプルプログラムを組んでみよう。
今回はまずレコードの表示、追加、削除、変更ができるプログラムを組む。


まず Xcodeで新規プロジェクトを作る。このとき "Use Core Data for storage" にチェックを入れておく。

続いてモデルを定義する。今回は Book というシンプルなエンティティを一つ用意した。

ビューを用意する。NSTableView を作り author と titile 列を作る。
モデルとビューの紐付けに NSArrayController を使う。

Modeを Entity とし、Entity Name に Book を指定する。これでモデルとつながった。
NSTableView内の NSTableColumnのバインディング設定を開、Array Controller を指定する。
これで MVCがつながった。
モデル(Book) ← コントローラ(ArrayController)←ビュー(NSTableView/NSTableColumn)

ただし CoreDataを扱うにはもう一手間必要で ArrayController に NSManagedObjectContext を渡す必要がある。今回 NSManagedObjectContextはコード内で生成している為、Interface Builderでは接続できない。この為、コード上で紐付けておく。
CoreDataTransaction_AppDelegate.m
- (void)awakeFromNib
{
[arrayController setManagedObjectContext:self.managedObjectContext];
}

arrayController はあらかじめ IBOutlet で定義し、InterfaceBuidlerで紐付けておく。
CoreDataTransaction_AppDelegate.h

@interface CoreDataTransaction_AppDelegate : NSObject 
{
       :
    IBOutlet NSArrayController* arrayController;
}


モデル(Book) ← コントローラ(ArrayController)←ビュー(NSTableView/NSTableColumn)
               ↓
                     CoreData(NSManagedObjectContext)


これでベースができた。後はデータ追加と削除のコードを付けておこう。
[+][ー]ボタンを作る。


NSArrayController には add: と remove: が用意されているので、それぞれ接続する。
これだけで新規追加と削除が行えるようになる。

さて動かしてみよう。追加、変更、削除が行える。



File メニューから Save を選択するとディスク(XML)に保存ができる。これは新規作成時のテンプレートが saveAction: を実装していて、メニューのSaveと紐づいている為。



ソース:
CoreDataTransaction at 2010-06-08 from xcatsan's SampleCode - GitHub


今日はここまで。

2010年6月7日月曜日

カテゴリでクラスメソッド定義

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

カテゴリはクラスメソッドもいける。

こうなら、

@interface Customer (Extension)
+(void)hello;
@end



+(void)hello
{
NSLog(@"hello");
}


普通に呼び出せる。


[Customer hello];



ファクトリメソッドなどの追加に使えそうだ。

- - -
近日ブログのリニューアル予定(URLが変わります)。