2009年09月8日, 1:50 上午
短短几天感觉自己老了好几岁,由于心情不好,减了10斤肉(因祸得福… 吧)。最近恐怕要迫于生计干和学一些非Mac开发的东西了,有些是老课题了,Cisco。曾经的挑战以失败落幕,不过未来的挑战在胜利之前是不会有落幕的时刻。
不知道自己现在是为了爱情,还是为了生计,或是为了将来。不过一如既往的努力,和100%的工作是我现在需要的了。
在完全备考CCIE之前,《我的佛典》还是需要一个更新升级的,需要更好的使用本地存储来解决新数据载入的问题,所以Core Data还会是我的讨论主题和研究方向。如何简单的整理数据,以便方便的增量更新也是个问题。
今天非常开心有一位佛友发了eMail给我,教我“郭师兄”。师兄当然是称不上了,但是我非常非常开心。新版MyFodian一定要完成,而且要尽快完成!
2009年09月6日, 6:42 下午
UINavigationController iPhone导航控制器/导航栏 是在iPhone程序中广为使用的用户数据互动方式。

这是一个简单的导航栏截图,我们可以设置其内置UIView的title,而导航栏会显示出这个title。而不是设置导航栏的title。我们也可以设置其左侧,或者右侧的按钮或者自定义视图对象。我们下面来一步一步的看看导航栏的使用:
1,创建并使用一个UINavigationController
UINavigationController *aNav = [[UINavigationController alloc] init]; |
然后添加一个视图进去,否则导航栏也没有意义的
UIViewController *aView = [[UIView alloc] initWithNibName: (*xib文件名*)];
[aNav pushViewController:aView animated:NO];
//导航栏的第一个视图不要动画化 |
2,设置导航栏的左右按钮:
我说过,设置导航栏的按钮并不是去设置导航栏本身,而是当时被导航的视图控制器,比如我们对aView作设置。
设置其标题:
aView.title = @"标题";
//配置一个按钮,我这里是《我的佛典》上的代码
UIBarButtonItem *callModalViewButton = [[UIBarButtonItem alloc]
initWithTitle:@"经文"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(callModalList)];
self.navigationItem.leftBarButtonItem = callModalViewButton;
[callModalViewButton release]; //由于本地视图会retain它,所以我们可以release了 |
可以看到,还是很简单的嘛。
3,其他常用方法和属性:
本地视图.navigationItem.leftBarButtonItem //左边栏项目
本地视图.navigationItem.rightBarButtonItem //右边栏项目
本地视图.navigationItem.backBarButtonItem //后退栏项目
本地视图.navigationItem.hidesBackButton //隐藏后退按钮(YES or NO) |
作为iPhone开发中最常用的对象之一,还有很多内容值得挖掘,不过今天就到这里了。祝愿大家在iPhone编程之路上一路快走!
2009年09月6日, 6:14 下午
我不知道为什么,不过有人搜索makeKeyAndVisible方法。其实我这种懒人一般不会刨根问底,有些方法照打就好,那些白给的方法有些就别动就好了。
我们看看这个每个程序都有的方法吧:
[window makeKeyAndVisible]; |
由于iPhone是单窗口程序,所以也就只有这么一个Window对象,而且是UIWindow,不是NSWindow。而根据文档上所说:
“这个是便捷方法,去使被使用对象的主窗口显示到屏幕的最前端。你也可以使用hiddenUIView方法隐藏这个窗口”
所以基本上来说,对于编程者的区别仅仅在于在其前添加代码,或在其后添加代码。
2009年09月6日, 1:09 上午
Three20是一个iPhone开发图形接口类的集合,包含图片查看,一般工具,HTTP本地缓存。Three20是来自于Facebook的iPhone程序源代码的。
添加Three20到您的程序
==============================
Three20是预编译静态库,最简单的方法是使用Xcode的依赖工程特性,下面是方法:
1. 复制(Clone命令)three20 git(GitHub) 目录: `git clone git://github.com/joehewitt/three20.git`. 确保将其储存在一个常用位置,以便Xcode每次编译时来索引和访问
2. 在 “three20/src”中找到 “Three20.xcodeproj” . 拖拽Three20.xcodeproj到您工程的根目录”Groups and Files”边栏中.在弹出对话框中去掉”Copy items”的对号,”Reference Type”选择”Relative to Project”然后点“Add”.
3. 现在要链接Three20库到您的工程。点击添加进来的”Three20.xcodeproj”,在“Details”表中,你会看到 libThree20.a. 打上文件右侧的对号
4. 现在你需要设置320库为你程序的依赖库,以便Xcode在编译的时候也会将320一起编译起来。展开左侧的“Targets”标签,双击您程序的“目标”文件。在“General”标签下,你会看到“Direct Dependencies”,点“+”号添加320库。
5. 现在你需要添加图片和字符串包到你的程序,找到”Three20.bundle”在”three20/src”中,然后拖拽到你的程序中。对话框里面“Copy items”别选,“reference type”选“relative to project”
6. 现在,你需要添加 Core Animation framework到你的工程。点击程序target,然后在frameworks里面添加 QuartzCore.framework就可以了(这个不是翻译的,原来的方法太麻烦了
7. 最后,我们需要让你的工程找得到320库的文件头。打开 “Project Settings”找到”Build”标签,找到 “Header Search Paths”双击它。添加到”three20/src”相对目录的地址。
8. 当你在 Project Settings, 找到 “Other Linker Flags”在”Linker”区,添加”-ObjC”和”-all_load”。
9. 完活了,在用320库的地方添加 #import “Three20/Three20.h” 就好了。
2009年09月6日, 12:57 上午
老话,最近闹心的事情多,开心的事情少,但是正事还是要干的。学习得需要,努力的需要,钱的需要… … 天上给我下点儿钞票吧!
言归正传,怎么在iPhone程序中读取PDF的内容呢?答案是,苹果为我们准备了一个很神奇的framework Q2D(Quartz 2D)。Q2D提供了全套的PDF读取API,接下来我们来看看如果简单的使用Q2D来读取PDF文件:
我建立了一个工程叫iPhonePDF, 添加了一个UIScrollView(不知道怎么添加UIScrollView? 添加一个UIView然后把interface上的UIView改成UIScrollView就可以啦…)名为PDFView
看看PDFView里面有什么吧
@interface PDFView : UIScrollView {
NSString *filePath;
CGPDFDocumentRef pdfDocument;
CGPDFPageRef page;
int pageNumber;
}
@property (copy, nonatomic) NSString *filePath;
@property int pageNumber;
-(CGPDFDocumentRef)MyGetPDFDocumentRef;
-(void)reloadView;
-(IBAction)goUpPage:(id)sender;
-(IBAction)goDownPage:(id)sender;
@end |
filePath是储存pdf文件的位置的,得到文件位置就是老话题了:[NSBundle mainBundle]… 后面的会写吧… 不记得了在我博客里面搜索吧
CGPDFDocumentRef是PDF文档索引文件,Q2D是Core Foundation的API,所以没看到那个星星~
CGPDFPageRef是PDF页面索引文件
pageNumber是页码
下面的几个函数其实一看就明了了,翻页的,和刷新页面的。第一个是自定义的getter
然后我们看看m文件里面有用的方法:
@implementation PDFView
@synthesize filePath,pageNumber;
- (void)drawRect:(CGRect)rect //只要是UIView都有的绘图函数,基础哟~
{
if(filePath == nil) //如果没被初始化的话,就初始化
{
pageNumber = 10; //这个其实应该由外部函数控制,不过谁让这个程序特别简单呢
filePath = [[NSBundle mainBundle] pathForResource:@"zhaomu" ofType:@"pdf"];
//这里,文件在这里!
pdfDocument = [self MyGetPDFDocumentRef]; //从自定义getter得到文件索引
}
CGContextRef myContext = UIGraphicsGetCurrentContext();
//这个我研究了一段时间呢,不过就照打就可以了
page = CGPDFDocumentGetPage(pdfDocument, pageNumber);
//便捷函数,告诉人家文档,告诉人家页码,就给你页面索引
CGContextDrawPDFPage(myContext, page);
//画!
}
//此getter可以考虑照打... 都是CF函数,我看到就恶心。
//其实不是很难了,得到文件,转换成URL,然后通过
//CGPDFDocumentCreateWithURL(url)得到文件内容索引
//Ta Daaa~~
- (CGPDFDocumentRef)MyGetPDFDocumentRef
{
CFStringRef path;
CFURLRef url;
CGPDFDocumentRef document;
path = CFStringCreateWithCString(NULL, [filePath UTF8String], kCFStringEncodingUTF8);
url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0);
CFRelease(path);
document = CGPDFDocumentCreateWithURL(url);
CFRelease(url);
return document;
}
-(void)reloadView
{
[self setNeedsDisplay]; //每次需要重画视图了,就call这个
}
-(IBAction)goUpPage:(id)sender
{
pageNumber++;
[self reloadView];
}
-(IBAction)goDownPage:(id)sender
{
pageNumber--;
[self reloadView];
}
@end |
我这个是个少半成品的程序呢… 我当时弄了几个PDF测试程序,但是找不到了。不过意思是一样的,剩下的东西由大家来发挥吧,有问题记得留言噢!我有问必答!
2009年09月5日, 11:41 下午
如果按照美国的规矩写文章,我恐怕就必须证明魔兽世界已经害死了多少人。但是我是中国人,我用中国字,我看到的是中国人能看到的。
是阿,魔兽世界不是唯一一个网络游戏,就算没有魔兽世界,在地球上还有那么多其他的网络游戏。但是这种假设没有必要,因为魔兽世界是现实存在的,而且已经害了很多人,我其实就是间接受害者。
不懂究竟魔兽世界有多好玩,不懂玩魔兽世界的人内心到底有多空虚。不懂魔兽世界究竟能带来怎样的快感,不懂魔兽玩家究竟能从中得到什么?我真是不懂阿!我没玩过?我玩过,为了学习其中宏怎么写,lua怎么用,但是最后发现不过是在帮wow害人而已。
是阿,我们的社会压力太大了,我们的家庭压力太大了,我们的学校压力太大了,该死的学习压力太大了。压力大还有很多方式方法来解决,压力大也不应该玩上就不停歇,压力再大这也是现实。魔兽中的一切的一切都是虚幻泡影,金币,银币,铜币,你最后真能用他们换来什么么?
醒来吧,醒来吧,不知道该用什么拯救你。醒来吧,醒来吧,现实还需要你来面对。
2009年09月3日, 8:08 下午
循环使用整个NSArray内的对象是非常常用的了,而且最近我在研究究竟怎么能方便的把NSArray存入Core Data,所以这更是必要了,看看如下的方法吧:
1,Objective-C 2.0法,最应该使用的
NSArray *aArray; //我们的Array,假设他已经初始化有内容了
for(id innerObj in aArray) //id可以由其他对象类型替代
{
//也就是说, 在循环中的参数innerObj就是aArray中的对象
//由于NSArray中只能储存对象,所以我们使用id作为内涵对象的类型,其实就是个指针了
//而且如果NSArray中的内容不一致,id更不会出现冲突
} |
2,C的老方法,不推荐,低性能
NSArray *aArray; //我们的Array,假设他已经初始化有内容了
for(int i=0;i<[aArray count]; i++)
{
[[aArray objectAtIndex:i] 然后作你想作的事情]; //做爱 作的事情...
} |
3, 用NSEnumerator(不知道怎么翻译阿….)
NSEnumerator* myIterator = [myArray reverseObjectEnumerator];
id anObject;
while( anObject = [myIterator nextObject]) //每次读取“逐读器”的下一个对象
{
//anObject和刚才的innerObj是一个意思,但是看看多了这么多行
} |
结语:
就用第一种方法吧….
2009年09月3日, 7:12 下午
1,operationQueue 里边应该可以同时添加多个operation吧?
是的,本来operationQueue的目的就是多线程管理,那多线程,可不只是一个线程。
而且我们可以设置这个队列每次被处理的“操作”数量
NSOperationQueue *aQ = [[NSOperationQueue alloc] init];
[aQ setMaxConcurrentOperationCount:10]; |
这里的setMaxConcurrentOperationCount就是同时被处理的“操作数”,参数为整数int或NSInteger (两个是一样的,不记得的可以在我的博客里面搜索一下噢~)
2,那main函数应该怎么写?
main函数中其实只需要写你要在另外一个进程里面作的事情。比如对于我来说,我常常只是作一个简单的事情,那我会用NSInvocationOperation,NSOperation的简化版。比如说:
NSInvocationOperation *aOpt = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(doSomeThing) object:nil];
- (void)doSomeThing
{
//读取大量大延迟数据等等
//可以使用performSelectorOnMainThread来将得来的数据返回到主线程
} |
在doSomeThing函数里面,我可以从网上读取一些东西,但是读取是需要占用时间,而堵塞主线程的。而使用NSOperation这样使用就不会了。
而如果是NSOperation,虽然复杂了一些,又是做一个NSOperation的子类。其实main函数做得事情和doSomeThing是一抹一样的。只不过如果你制作这个子类,你对其操作的内容可以更多,可以制作更复杂的读取,载入操作等等,而且你可以重复使用这个类功能阿。再者,NSOperation也提供了对runtime操作的支持,不过那就太麻烦了,一般不大用的上。
最近麻烦事情真是太多了,而且还都不顺利,死的心都有阿。还好有这么多好朋友支持我,我这个博客也一点儿一点儿的有回复了…大家别那么冷漠,管我写的好还是不好,按东北话来说“吱一声”嘛~唉,我要加油阿!我还有那么多的事情没办到呢,怎么能放弃!他妈的!!!!!阿!!!!!!
2009年09月1日, 2:02 下午
大家都有Snow Leopard和XCode 3.2了吧?会发现XCode变了不少,帅拉!

那我们点击“Create a new Xcode project”来开始我们的Core Data程序工程吧!

在这里,XCode已经给我们准备好了一个几乎可以直接去用的程序模板,直接选择“基于导航的应用程序”,然后记得点选“Use Core Data for storage”

建立好的程序名为XCDtest01,我们尝试编译运行,看看得到的程序是什么样的:

基本上来说,这个程序把什么都给我们弄好了,一个程序,在点击添加按钮之后添加现在的时间标签,如果点击“Edit”编辑按钮,就进入编辑模式,可以删除任意条信息。
如果点开xcdatamodel文件,我们可以看到,其中的实体为Event,有一个参数,名为“时间标签”。也就是说,如果我们想对这个列表视图中的数据作更改,只需要适当更改这个实体的参数,并配置- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 代理条目就可以显示适当的内容了。

这个预置程序与我们之前讨论的程序不同的,在于这个程序中并没有配置一个可变数组(NSMutableArray)来作数据副本,以达到高速存储的目的。因为Core Data在向磁盘和内存操作,NSMutableArray是内存操作,速度上比较有优势。但是我们有的这个小程序太小了,再者苹果有可能认为那种方法是非标准的。所以在这里才没有那么作
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [[managedObject valueForKey:@"timeStamp"] description]; |
在这个程序的cell配置代理里面,仅仅是从“获取操作控制器”中得到了“被管理对象”,然后再读取其中的内容到cell的text中。
希望大家也使用这个模板,自己创建一个Core Data程序,然后简单的理解一下代码。下次我们聊只使用基于Window的程序模板+Core Data来创建程序
2009年09月1日, 1:54 下午
今天晚些时候或者最近会一步一步的制作一个简单的Core Data程序。Core Data确实是个好玩的东西,不多写写是不行的。
最近心情比较差,失恋都失恋大发了,就像饿过了就不饿了~感觉人又成熟了,看多了,见多了,想多了,悟道的也就多了
借郭德纲的定场诗:
守法朝朝忧闷,强梁夜夜欢歌。
损人利己骑马骡,正直公平挨饿。
修桥补路瞎眼,杀人放火儿多。
我到西天问我佛,佛说——我也没辙。
再借某人的博客上的话(http://blog.sina.com.cn/s/blog_5e60c5b60100df90.html)
是的,没辙。很多事情是没辙。但世上本是没有辙的,走的车多了,就有辙了。所以,光感叹没辙是没辙的。有辙的唯一办法就是——发动车,上路。
他说得不错,有功夫想辙,还不如直接去干,直接去做。发动车是不行了,我手头还没车,人家都有跑车了… 作自己能做得,做到最好吧!管它三七21,九九81,缘亦如此矣,报应如此矣。
皈依我佛,皈依法性,再不行就自皈依僧当个高科技和尚吧,哈哈~