第七章, Core Data Basics

這章主要講解如何使用 Cocoa 的 NSManagedObject 來做簡單的數據管理程序。
Core Data 是一個很方便的功能,利用它,可以幾乎不用寫任何代碼,就可以做出基本的數據管理程序,比如倉庫管理,人員管理之類的。
使用 Core data templet 來創建 Project,只需要建立好 Model,Xcode 會自動生成各種對應 GUI 的 Binding。
使用內置的 Data Model 編輯器,建立好 Model, 然後打開 NIB, 並把 data model 從草圖拖動 到 IB 的 Windows 上,就可以自動生成 GUI。生成後,所有的 Binding 已經建立。基本上已經可用了。
如果需要為已經建立的程序制定功能,必須 subclass NSManagedObject.
書中第 159 頁漏掉一段,如下:
In order to customize NSManagedObject's behavior, we need to create a subclass, and update our data model so that it knows there's a specific class to use for the MythicalPerson entity. Create a new Objective-C class in your project, by right-clicking on the folder you want to add it to, and selecting "Add->New File..." from the context menu. Use the assistant that appears to create a Cocoa/Objective-C class. Depending on your version of Xcode, you may be able to specify you want a subclass of NSManagedObject here. Do so if you can, but otherwise NSObject will do, we'll fix it after saving.. Click "Next", name the new class "MythicalPerson", and click "Finish". If your version of Xcode didn't let you pick NSManage- dObject as the superclass for your new class, now's the time to go into the @interface declaration in MythicalPerson.h, and change the superclass to NSManagedObject.
Now that the class is in place, go back to the data model we created earlier, select the MythicalPerson entity, and change its class name from NSManagedObject to MythicalPer- son. Save your work, and you've now got a model class of your own, ready for customizing.
這段很重要,但是沒有在書上印出來 =_=
如果需要驗證某個 property ,需要 subclass NSManagedObject, 並 Implement
-(BOOL)validate<key>:(id *)ioValue error:(NSError **)outError
比如書上的例子:
-(BOOL)validateName:(id *)ioValue error:(NSError **)outError
{
if (*ioValue == nil){
return YES;
}
if ([*ioValue isEqualToString:@"Bob"]){
if (outError != NULL) {
NSString *errorStr = NSLocalizedString(
@"You're not allowed to name a mythical person 'Bob'."
"'Bob'is a real person, just liek you and me.",
@"validation:invalid name error");
NSDictionary *userInfoDict = [NSDictionary dictionaryWithObject:errorStr forKey:NSLocalizedDescriptionKey];
NSError *error = [[[NSError alloc] initWithDomain:@"MythicalPersonErrorDomain" code:13013 userInfo:userInfoDict] autorelease];
*outError = error;
}
return NO;
}
return YES;
}

目前比較讓我摸不著頭腦的是 NSError 的方法們,應該用多了就能熟悉。
還有就是驗證多個 properties, 需要 Implement
- (BOOL)validateForInsert:(NSError **)error
- (BOOL)validateForUpdate:(NSError **)error 
這兩個方法。

Posted by Daddy

2010/04/26 19:42 2010/04/26 19:42
Response
No Trackback , No Comment
RSS :
http://crumpz.info/tc/Daddy/rss/response/171

这章就是教你怎么自己做 Alert Panels. 就是你要做什么事情之前弹出个窗口问你是否继续阿, 是否退出阿, 是否取消阿之类的东西.
Challenge
Add to the Alert sheet another button that says Keep, but no raise. Instead of deleting the employees, this button will simply set the raises of the selected employees to zero.

这个我很纠结地试了很久, 最后还是上网查了. 然后查出来的方法其实之前也有想过, 但不确定, 也不知道该怎么用. 学习了.
添加修改的源码:
-(IBAction)removeEmployee:(id)sender
{
NSArray *selectedPeople = [employeeController selectedObjects];
NSAlert *deletionAlert = [NSAlert alertWithMessageText:@"Delete or clear raise?"
defaultButton:@"Delete"
alternateButton:@"Cancel"
otherButton:@"Clear"
informativeTextWithFormat:@"Are you sure that you want to remove or clear %d people?",[selectedPeople count]];
[deletionAlert beginSheetModalForWindow:[tableView window]
modalDelegate:self
didEndSelector:@selector(alertEnded:code:context:)
contextInfo:NULL];
}


-(void)alertEnded:(NSAlert *)alert code:(int)choice context:(void *)v
{
if (choice == NSAlertDefaultReturn)
{
[employeeController remove:nil];
}
else if (choice == NSAlertOtherReturn) {
NSArray *selectedPeople = [employeeController selectedObjects];
for (Person *p in selectedPeople){
//这是 for 很基本的用法...
//[p setExpectedRaise:0.0]; //通用的写法.
//setExpectedRaise 是 expectedRaise 的 setter, 由@property &
//@synthesize 自动生成. 不是我定义的, 但我仍然可以使用, 或者重写.
//但在 Objective-C 2.0, 这也可以写成:
p.expectedRaise=0.0; //新的写法. }
}
else {
return;
}
}

其实昨天也刚刚学到, MVC之中 Controller 是不储存任何数据的, 怎么今天就忘记了呢...
强力极力推荐 iTunesU 上的 Stanford University - iPhone Application Development (Winter 2010), 看了几课, 很多看书的时候很模糊的东西也慢慢清晰起来了. 虽然它是说 iPhone 的, 但这种东西一样通百样的. 真的是很不错, 免费的大学课程页~~~~

Posted by Daddy

2010/04/07 12:23 2010/04/07 12:23
Response
No Trackback , No Comment
RSS :
http://crumpz.info/tc/Daddy/rss/response/169

第 14 章教我們如何使用 NSNotification.
The naming convention is simple: Start with the name of the notification. Remove NS from the beginning, and make the first letter lowercase. Remove Notification from the end. Add a colon. For example, to be notified that the window has posted an NSWindowDidResizeNotification, the delegate would implement the following method:

- (void)windowDidResize:(NSNotification *)aNotification

這節比較有繞.... 我回頭還會再來看的..
Challenge
Make your application beep when it gives up its active status. NSApplication posts an NSApplicationDidResignActiveNotification notification. Your AppController is a delegate of NSApplication. NSBeep() will cause a system beep.
非常簡單, 根據上面的 naming convention, 以下是添加在 AppController.m 裡的源碼:
-(void)applicationDidResignActive:(NSNotification *)note
{
NSBeep();
}

Posted by Daddy

2010/04/06 12:14 2010/04/06 12:14
Response
No Trackback , No Comment
RSS :
http://crumpz.info/tc/Daddy/rss/response/168

好的, 從 12 到 13 章說得都是如何控制 User default . 12 說得是怎樣做一個 Property 設定對話框, 13 說得是怎樣儲存, 讀取用戶的設定. 而這章的 challenge 就是
Add to the Preferences panel a button that will remove all the user's defaults. Label the button Reset Preferences. Don't forget to update the Preferences window to reflect the new defaults.

很簡單, 做一個按鈕, 然後將 default value 存到 NSUserDefaults 指定的地方即可.
Challenge 部分源碼:
//  PreferenceController.h
#import <Cocoa/Cocoa.h>

extern NSString * const BNRTableBgColorKey;
extern NSString * const BNREmptyDocKey;

@interface PreferenceController : NSWindowController {
IBOutlet NSColorWell *colorWell;
IBOutlet NSButton *checkbox;

}
-(IBAction)changeBackgroundColor:(id)sender;
-(IBAction)changeNewEmptyDoc:(id)sender;
-(IBAction)resetUserDefault:(id)sender;
-(NSColor *)tableBgColor;
-(BOOL)emptyDoc;
@end
//  PreferenceController.m
-(IBAction)resetUserDefault:(id)sender;
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[colorWell setColor:[NSColor whiteColor]];
[checkbox setState:1];
NSColor *color = [colorWell color];
NSData *colorAsData = [NSKeyedArchiver archivedDataWithRootObject:color];
[defaults setObject:colorAsData forKey:BNRTableBgColorKey];
[defaults setBool:[checkbox state] forKey:BNREmptyDocKey];
}

當然 IB 裡面要做連接.....= =

Posted by Daddy

2010/04/04 15:12 2010/04/04 15:12
Response
No Trackback , No Comment
RSS :
http://crumpz.info/tc/Daddy/rss/response/167

iPad


先來開箱/開機

再來使用中的種種.

Posted by Daddy

2010/04/03 15:33 2010/04/03 15:33
Response
No Trackback , No Comment
RSS :
http://crumpz.info/tc/Daddy/rss/response/166

終於, 不用拼命抓圖了...
多虧了這個 插件, 雖然還不能正確 Highlight Objective-C, 不過已經很好了...

好的, 第八章 Challenge
In the first edition of this book, readers created the RaiseMan application without using NSArrayController or the bindings mechanism. (These features were added in Mac OS X 10.3.) To do so, readers used the ideas from previous chapters. The challenge, then, is to rewrite the RaiseMan application without using NSArrayController or the bindings mechanism. Bindings often seem rather magical, and it is good to know how to do things without resorting to magic.

實際上, 這個Challenge, 源碼就在書上, 就是讓你打一次, 增強記憶, 然後再加入 column sorting 的功能. 但是, 事實證明, 真的, 看題目要看完...我因為沒有翻到後面的源碼, 導致自己在那邊一邊抓頭, 一邊寫從來不知道該怎麼做的同時更新兩個 column, 書上沒說....不管我怎麼做,  兩個 columns 都在那邊添加一樣的東西, apple dev doc 上面也只是說要拿到 column identifier 什麼的...後來凌晨7點多了, 沒辦法, 又看了一眼書, 差點沒暈死過去...源碼!!!!於是懷著怨恨的心情, 寫了一遍. 原來如此阿..然後它這個challenge實際上是要你熟悉一下不用binding應該怎麼處理這種...雖然我傻傻地分不清楚, 也總算在磕碰的過程中基本明白了 NSTableView 的一些用法.

但問題又來了, 還要求我要給這個 tableView 加上 sorting 的功能, 書上的例子是這樣的(改了一點):

-(void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray *)oldDescriptors
{
[employees sortUsingDescriptors:[aTableView sortDescriptors]];
[tableView reloadData];
}

但不管怎麼說, 當我按下想要排序的表格header的時候, 這個卻不會被 call. 然後我又找阿找, 找啊找. 終於後來給我找到了, 要他媽的在 XCode裡面設定....

要設定好 Sort Key 這裡, 然後上面那個才會被 call, 實在很賤....書上也不說....
不管怎麼說, 總算是完成了.

源碼, 猛擊放大:

Person.h

Person.m

MyDocument.h

MyDocument.m


Posted by Daddy

2010/03/21 19:28 2010/03/21 19:28
Response
No Trackback , No Comment
RSS :
http://crumpz.info/tc/Daddy/rss/response/164

考试....考试真是好东西阿.....昨晚上发现, 我俨然已经忘记 C 的语法了....
Challenge 的要求是:
Make a to-do list application. The user will type tasks into the text field. when the user clicks the Add button, you will add the string to a mutable array, and the new task will appear at the end of the list.

用户插入图片
这个 challenge, 充分体现了中国和美国的教育的不同处....因为 Challenge 又说了:
You get extra points for making the table view editable. (Hint: MSMutableArray has a method -replaceObjectAtIndex:withObject:.)

也就是说, 要做到能够修改已经加入到表格里面的东西. 但这本书, 我读到这里顶多说到如何把东西加入到表格里, 可没说怎么改表格. 我的意思是, 表格当然理论上是可以改的, 但是书上没说阿...然后经过一番痛苦地抓头, 我做了个 Edit 按钮...基本上, 选定表格里需要修改的行, 然后在上边按 Edit 就可以把 textField 里面的字修改...

我这里说的教育的不同处是, 我这个在国内上过几年学的, 已经深受毒害了...书上没有的, 我就不知道如何是好了....其实苹果网站上面有解说怎么编辑表格.....我以后一定善用这个知识库.....
toDo.h
用户插入图片








toDo.m

这个-(void)tableView:(NSTableView *)aTableView
  setObjectValue:(id)anObject
  forTableColumn:(NSTableColumn *)aTableColumn
             row:(int)rowIndex
就是书上没有的....5555555 我以后一定要查资料,我以后一定要查资料.....

Posted by Daddy

2010/03/18 15:21 2010/03/18 15:21
Response
No Trackback , a comment
RSS :
http://crumpz.info/tc/Daddy/rss/response/162

恩, 最近在學這本書. 看到了 Chapter 4, 有個 Challenge.
雖然很簡單, 但也花了幾個小時....我發現, 考試真的是很重要的, 不然都不知道之前學了啥....
就一個 character count的東西

Create an application that can have only one window open, so it is not a document-based application. Figure 5.13 shows the window before any input has been added. Figure 5.14 shows the window that the application will present to the user.

用户插入图片
程序如下:
countCharClass.h
用户插入图片
countCharClass.m
用户插入图片
繼續努力.....

Posted by Daddy

2010/03/13 15:51 2010/03/13 15:51
Response
No Trackback , No Comment
RSS :
http://crumpz.info/tc/Daddy/rss/response/161

你見過鬼嗎?

最近看了一些天涯網友收集的鬼故事,大部分是聲情並茂地講述自己或者是朋友或者是哪裏聼來的恐怖怪事。放在電話裏,每天上班下班坐車的時候都看看,其中不乏一些讓人看完脊背發涼的故事。故事嘛,沒事消遣看看就好。

小時候是挺相信這世界上有鬼的,但長大之後就漸漸地不會去太在意這些生活10小時以外的東西了。小孩子時間是很多的,放學回家之後就完全是自己的時間,什麽都不用考慮,真懷念呀。小時候很喜歡聼這些故事,越聼越害怕,越害怕越想聼。經常在睡覺之前要求媽媽講一個故事,而我媽都會給我講我外公的故事。基本上就是說我外公是個年輕帥哥的時候就死掉了,是本地醫院的院長,算是青年才俊英年早逝。聽説他年輕的時候,是一個身體很差的人,所以經常會被女鬼迷。所以他身上都會帶一些避邪的東西,那些鉄制的東西據説是可以克制這些女鬼什麽的。(事實上,看過supernatural的人就知道,他們實在沒有東西可用的時候,就直接抄鐵棍起來打鬼,可以暫時把現形的鬼魂打散。)我就記得有一次,我媽說我外公上山勞作的時候(當年就算是醫院院長也是需要上山.....),就踫到了一個女鬼,當時是下午,他剛好沒有帶那些避邪的東西,勞動累了就坐在陰涼処休息,有個女鬼在他面前出現,他於是就拿起鋤頭,在一塊大石頭上敲了下去,就嚇跑了女鬼。但可能因爲他的體質不是很好,還是于我出生之前就去世了,所以他是什麽樣子我就從來沒有見過,遺像的手筆也不是很好,但是基本上可以看出是一個帥哥,嗯。

現在呢,我不敢說這個世界上有鬼,但也不能說沒有。因爲本來從小學開始就不太相信鬼神這種事情的,但是有一件事我印象很深,直到現在我還有時候想起來還會惦記——我到底看到的是什麽?

那時候我在琯頭中心小學上 4 年級,班上有一個很要好的女同學,叫張榕,依稀記得是個有點肉肉的小美女。我們住的比較近,所以那時候我們經常一起上學放學做作業什麽的。她家門口的臺階很高,可能是地基比較高,所以那個臺階上去起碼有1.3米左右吧。 那时候是夏天,下午放学之后我回家,然后就去我外婆家吃饭。我家跟我外婆家住很近,四十几米的距离,中间会经过张榕的家,然后转个弯就到我外婆家。当我从我家出来,经过了张榕家门口的台阶,就快要到转弯的时候,迎面走来了张榕的妈妈。我叫了她一声“阿姨”,但是她没有理我,看上去脸黑黑的,满面怒容,看上去就是很生气很生气的样子,径直从我身边走过回家了。我当时觉得有点奇怪,因为我有时候也会去她家请教些作业什么的,她不至于会对我视而不见,而且还怒气冲冲的样子。但我也没有放在心上,就去外婆家吃饭,至于后来做了什么就不记得了,太久了。

第二天早上,我照旧去上学。但是站了一会儿没看到张榕出来,我也就自己一个人去上学了。因为不会互相约好,所以我想她可能已经去学校了。谁知道到了学校,还是没看到她,接着就是中午放学。回到家里,我妈妈就跟我说了一件让我感觉难以置信的事情。

原来,张榕的妈妈昨天早上乘车去福州办事,但是下午回来的路上,遇上了车祸,來不及送醫院就死了。

那麽,昨天下午放學后,我在她們傢門口遇見的那位怒氣衝衝,滿臉黑氣,對我的問好視而不見的阿姨又是誰?

過了大概一個禮拜左右,張榕又來上學了,手臂上還帶著一朵象徵性的花(我們這邊的風俗)。於是我小心翼翼的上去問她是不是誰出事了。她還是比較冷靜的,告訴我她媽媽遇到車禍去了。我不記得當時我有沒有安慰過她,但是我沒有把那天下午的事情告訴她。

後來不記得過了多久,她搬家去了其他地方,我們就斷了聯絡了。

是我眼花?

Posted by Daddy

2009/12/16 17:19 2009/12/16 17:19
Response
No Trackback , a comment
RSS :
http://crumpz.info/tc/Daddy/rss/response/160

找質數(prime number)

最近又開始玩 C 了。今天剛好看到有人問怎麼找出從1到100之間的質數,不過他問的是RUBY的寫法。沒關系,不影響我研究。。。想了一天,寫出來了。。。這東西真費腦子阿,但是是不錯的鍛煉。
用户插入图片

基本上,只要數字不是太大,比如1-100000也只需要兩三秒左右。
話說回來, Xcode 的 IDE真好,用起來很舒服。應該是比WINDOWS下面任何一個IDE用的都舒服吧。。。。感謝大刀大爺指導。

Posted by Daddy

2009/11/27 23:03 2009/11/27 23:03
Response
A trackback , a comment
RSS :
http://crumpz.info/tc/Daddy/rss/response/159

« Previous : 1 : 2 : 3 : 4 : 5 : ... 15 : Next »

블로그 이미지

就这么走下去.....

- Daddy

Notices

Archives

Authors

  1. Daddy

Calendar

«   2010/09   »
      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    

Site Stats

Total hits:
201424
Today:
26
Yesterday:
26