不时需要用计算一些公式来验证算法的正确性, 以前在Windows下面都是使用Maple来对付, 但是Maple太过强大了点, 用得时候总觉得在用牛刀杀鸡.
今天找了下居然让我发现了个Mac下面强大的计算器 – Magic Number Machine.

公式计算就不用说了, 上图就能看出来了, 它简直是为程序员量身定做的. 强烈推荐使用!
这里是它的主页.
今天在尝试抓取起点中文网首页的时候遇到了一个问题 — 如果编码没有用对的话是没办法读取任何东西的.
这也算是C#用的太多养成的坏习惯, 以前基本没怎么考虑过编码问题. 应该说, C#里面就算编码错了, 也能读进来东西, 只是一片乱码而已. Cocoa里面就狠了点, 直接抛异常了.
下面是刚开始写的一段代码, 把起点中文网的主页下载到一个字符串中.
1 2 3 4 5 6 7 8 9 10 11 12 | NSURL *url = [[NSURL alloc] initWithString:@"http://www.cmfu.com"]; NSError *error; NSString *xml = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error]; if(xml == nil) { NSLog(@"Error reading url at %@", [error localizedFailureReason]); } else { [result setString:xml]; } |
死活下载失败, 错误信息就是编码不对. 好吧, 我打开了帮助查看了下所有的编码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | enum { NSASCIIStringEncoding = 1, NSNEXTSTEPStringEncoding = 2, NSJapaneseEUCStringEncoding = 3, NSUTF8StringEncoding = 4, NSISOLatin1StringEncoding = 5, NSSymbolStringEncoding = 6, NSNonLossyASCIIStringEncoding = 7, NSShiftJISStringEncoding = 8, NSISOLatin2StringEncoding = 9, NSUnicodeStringEncoding = 10, NSWindowsCP1251StringEncoding = 11, NSWindowsCP1252StringEncoding = 12, NSWindowsCP1253StringEncoding = 13, NSWindowsCP1254StringEncoding = 14, NSWindowsCP1250StringEncoding = 15, NSISO2022JPStringEncoding = 21, NSMacOSRomanStringEncoding = 30, NSProprietaryStringEncoding = 65536 }; |
我一个一个的试, 居然全都不行! 崩溃了, 这都什么年代了, 难道Cocoa还不支持中文? 不可能啊. 估计是上面那份文档里面只是列出了最长用的几种编码(这里是苹果认为最长用的, 可见对于中国基本是无视了, 鄙视下!), 我就写了下面这段代码输出了所有支持的编码:
1 2 3 4 5 6 7 8 9 | const NSStringEncoding *encodings = [NSString availableStringEncodings]; NSMutableString *str = [[NSMutableString alloc] init]; NSStringEncoding encoding; while ((encoding = *encodings++) != 0) { [str appendFormat: @"%@ === %in", [NSString localizedNameOfStringEncoding:encoding], encoding]; } [result setString: str]; |
好家伙, 果然被我猜中了, 下面就是所有支持的编码列表
对我来说, 屏幕截图和录像的需求非常大.
1. 写Blog, 免不了经常需要截各种图.
2. 遇到了问题, 请教别人的时候往往一张屏幕截图比千言万语都有效.
3. 教别人的时候, 屏幕录像能帮大忙.
最开始用的都是Windows著名的”PrintScreen”, 然后用画图修改一下. 后来有了专门的抓图软件, 可是都没有跳出单纯抓图或者录像这个圈子, 顶多就是抓图的功能强一些.
一般来说, 大部分时候我都需要抓图, 转换格式, 上传到某个网站, 复制图片地址, 然后才能在Blog里面使用.
如果要做演示视频就更加麻烦了, 自己录像之后要需要花很多时间转换格式并压缩大小, 然后还要找到一个支持上传视频的空间.
一直到我遇到了 — Jing.
它除了提供强大的抓图和录像功能之外, 还提供直接保存到在线账户的功能, 简直就是为我量身定做的.
说得再多都不如看演示视频来得直接 点击观看在线演示.
最后一点让我特别喜欢的 — 这么强大的软件居然是免费的!
我想这应该未来软件发展的趋势, 软件免费, 服务收费. 当然, 现在Jing的在线服务还是免费的哦.
NSTask的作用相当于C#里面的Process, 都是用来启动外部进程的.
让我意外的是, 它的用法和Process都差不多.
废话不提, 范例程序先上.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | - (void)runExternalProcess { NSTask *task = [[NSTask alloc] init]; NSPipe *pipe = [NSPipe pipe]; NSFileHandle *readHandle = [pipe fileHandleForReading]; NSData *inData = nil; [task setStandardOutput:pipe]; [task setLaunchPath:@"/usr/bin/curl"]; [task setArguments:[NSArray arrayWithObject:@"http://blog.codingmylife.com"]]; [task launch]; while((inData = [readHandle availableData]) && [inData length]) { NSString *temp = [[NSString alloc] initWithData:inData encoding:NSUTF8StringEncoding]; } [task release]; } |
这个范例演示了启动系统自带的curl下载我的Blog的首页并且拿到curl的输出.
需要拿到外部程序的输出经常用在调用控制台程序和脚本方面, 一般来说我们并不需要知道输出结果, 只要把外部程序启动就好了.
那么这段程序可以简化成这个样子:
1 2 3 4 5 6 7 8 9 10 | - (void)runExternalProcess { NSTask *task = [[NSTask alloc] init]; [task setLaunchPath:@"/usr/bin/curl"]; [task setArguments:[NSArray arrayWithObject:@"http://blog.codingmylife.com"]]; [task launch]; [task release]; } |
学习了一段时间的objective-c, 总有个地方让我觉得不太舒服 – 类里面的方法只有两种, 静态方法和实例方法.
这似乎就不是完整的面向对象了, 而且在设计的时候也总是觉得不太舒服, 本来OO的原则就是一个对象只暴露有用的东西. 如果没有了私有方法的话, 对于一些小范围的代码重用就不那么顺手了.
总觉得对外暴露一个没用的东西实在是丑陋.
好在今天终于知道了如何在类里面声名一个私有方法(objective-c的高人不要笑话):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @interface Controller : NSObject { NSString *something; } + (void)thisIsAStaticMethod; - (void)thisIsAnInstanceMethod; @end @interface Controller (Private) - (void)thisIsAPrivateMethod; @end |
也许通过这个方法也能实现 protected, sealed 等等的方法.
这是一部神奇的电影, 主角杀了很多人, 但是我确没有觉得他是个杀人犯.
看到了很多裸体, 恐怕是我在银幕上看到最多的一次, 但是我确没有感到一丝的色情.
看到主角死亡, 被一群人活生生吃掉, 尸骨无存, 我却没有感到一点的难过或者高兴, 似乎这就是他最自然的归宿.
我说不清楚自己到底感受到了什么, 只是心里固执的认为我被打动了. 就像突然之间觉得自己很高兴, 但是仔细一想确不知道为了什么一样. 我很莫名的被打动了.
我觉得最能概括我现在感觉的就是电影一开始的一句旁白: 到了十岁, 他终于学会了说话. 但是随即他就发现语言无法形容他闻到了什么.
我现在就是这样的状态, 所知道的语言没有办法准确的形容我的感觉.
只是依稀记住了这样一个公式: 生命的味道 + 爱的味道 = 天使的味道
不对, 没有这么俗气. 因为我在写出上述公式之后居然在自己心里发现了”亵渎”两个字.
片中那个意大利香水师在教主角萃取植物精油的时候说过, 这一滴一滴的精油, 就是玫瑰花灵魂的精华.
那么主角最后得到的难道是”人类灵魂的精华”???!!!!! 是了, 至少我相信是这样的.
只有这样的东西才能解释片中那瓶小小的香水的无比威力, 没有人能够拒绝来自灵魂深处的打动, 没有人能够抗拒灵魂中最精华部分的吸引 – 那是纯粹无比的爱.
到了这里, 我想我可以写出这个等式了: 人类灵魂的精华 = 爱 = 天使. 似乎也可以这样理解, 天使就是人类想象中最纯粹的爱的化身.
我的Blog系统使用的是WordPress, 架在盘古的服务器上的, 盘古使用的管理系统是cPanel, 因为经常需要备份所以就写了个简单的脚本来下载数据库备份和主目录的文件备份.
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 | set d to current date set y to year of d set m to month of d as integer set d to day of d set formated to (m & "-" & d & "-" & y) as string set login to "curl -d \"user=你的用户名&pass=你的密码\" -D cpanel.txt www.codingmylife.com:2082/login" set getDB to "curl -o ~/备份/blogdb-" & formated & ".gz -b cpanel.txt http://www.codingmylife.com:2082/getsqlbackup/blog.gz" set getBlog to "curl -o ~/备份/backup-codingmylife.com-" & formated & ".tar.gz -b cpanel.txt http://www.codingmylife.com:2082/getbackup/backup-codingmylife.com-" & formated & ".tar.gz" my growlRegister() growlNotify("info", "正在登录") do shell script login growlNotify("info", "正在备份数据库") do shell script getDB growlNotify("info", "正在备份主文件夹") do shell script getBlog growlNotify("info", "备份完成") using terms from application "GrowlHelperApp" --Register Growl on growlRegister() tell application "GrowlHelperApp" register as application "BackupBlog" all notifications {"Alert"} default notifications {"Alert"} icon of application "Script Editor.app" end tell end growlRegister on growlNotify(gtitle, gdescription) tell application "GrowlHelperApp" notify with name "Alert" title gtitle description gdescription application name "FanFou" end tell end growlNotify end using terms from |
把上面脚本中”你的用户名”,”你的密码”和”www.codingmylife.com”换成你自己的信息就可以了.
“生命正是因为会死亡, 所以才珍贵” — 大法师雀鹰
“拒绝死亡, 就是拒绝活着” — 大法师雀鹰
到底什么才算是珍贵? 我看完这部动画片之后得到了答案.
需要历经艰辛才能得到的东西就叫珍贵.
普通人, 就像你我, 或为了生活, 或为了买车买房, 或为了拥有一件自己心仪很久的东西, 拼命工作, 经历种种, 为的就是更好的活着. 因为有期盼, 因为总可以通过努力得到某些满足, 所以我们的生活虽然没有惊涛骇浪, 但是不缺充实. 正因为这样, 普通人们很少回去思考为什么活着, 因为我们需要通过经历艰辛才能得到生活.
纨绔子弟, 生下来就衣食无忧, 所有的东西都予取予求, 普通人终其一生都得不到的东西, 他们可以不费吹灰之力就得到. 他们是幸运而又不幸的, 如果天资聪慧, 那么他们很容易可以成就一番大事. 可是天才毕竟是少数, 剩下的就是可怜了. 因为生活没有任何艰难, 所以他们不明白什么叫做珍惜, 甚至不知道为什么活着. 他们的荒唐行径只不过为了找到自己活着的证据.
上天是公平的, 不需要付出就可以得到的东西, 往往伴随着这样那样的致命缺陷.
写到这里脑子里不由自主的想到了一些专业的东西:
数据绑定技术 — 简单, 方便, 可是没了灵活性, 需要付出更多的代价才能使之适应各种情况.
Ruby on Rails — 简单, 超高开发效率, 可是执行效率不能适应大型应用.
反射 — 灵活, 强大, 这些都是以放弃执行效率为代价.
O/R Mapping — 方便, 适应性好, 隔离性好, 也是执行效率和灵活性不够.
所以, 有经验的程序员在面对看起来简单而又强大的东西时, 第一个反应就是肯定存在什么致命的缺陷.
天下万理相同, 当你面对什么突如其来的好事的时候, 就需要好好思量一下, 因为需要付出的代价肯定不是一般人能够接受的.
十多年以前, 程序员这三个字的含金量比现在高太多, 为什么? 因为C/C++, 汇编都是很难学的语言, 能够掌握的人都是付出过艰辛的努力和战胜了孤独的.
反观现在, 程序员已经是随处可见, 因为Java, C#等新时代的语言通过隐藏底层的细节和简单明了的语法大大的降低了学习的门槛和难度. 可是我们真得应该庆幸吗? 这样不需要付出太多努力就能掌握的东西, 通常价值就是有限的.
曾和同事有过一个讨论, 我们有个共识, 随着硬件的日益强大, 程序语言抽象程度越来越高, 越来越易学易用. 程序员这个职业的技术含量会越来越低. 到了那个时候, 只有懂得底层技术的人才能站在这个行业金字塔的顶端.
前辈经常说, 再掌握了高级语言之后, 就静下心来, 重新捡起最基础的东西, 反复琢磨. 这就是提高自己境界和技术能力的不二法门. 确实, 这是真理. 当你觉得自己的能力不再增长的时候, 就需要停下来看看, 是否自己的地基到了该进一步稳固的时候了.
记得看过很多玄幻和武侠的小说, 绝顶的功法都有一个特点, 练到一定程度之后就需要忘记种种招式, 忘记种种技巧, 重头开始.
程序功力何尝不是这样? 到了一定的时候就需要忘记种种华丽的技巧, 忘记种种便捷的框架, 重头开始思考.
天行健, 君子以自强不息.
数据绑定在C#里面实现的很强悍, 可以减少非常多的代码, 主要用在展示数据和一些简单的增删改操作上面. 局限性也非常明显, 对于一些需要对数据展示和修改有较高自定义要求的地方就实战不开了, 远不如自己控制来得灵活.
今天学习了一下Cocoa的数据绑定, 感觉和C#的类似, 同样可以减少代码量, 同样也存在较大的局限性. 好了, 是骡子是马拉出来溜溜就知道了.
今天要做的东西是个简单的帐簿, 用来记录一下现金账务(做这个东西也是有原因的… 以前在Windows下面都是用的Excel来做记录的, 转到Mac下面之后找不到好用的电子表格…).
主界面如下

More
Cocoa里面有个概念叫做”Key-Value Coding”, 此前一直都没有搞清楚到底什么意思, 今天详细的读了一下资料之后算是彻底明白了, 下面就分享一下我的理解. 因为我也是刚刚开始学习Cocoa, 如果发现任何错误, 请马上告诉我. 先谢过
.
Cocoa所使用的主要编程语言Objective-C也是单根继承语言(类似的语言还有Java, C#等等), 也就是说所有的类都继承自NSObject. 而NSObject定义了两个非常有用的方法 – 一个读取变量值, 一个通过名称来设置变量值:
1 2 | - (id)valueForKey:(NSString *)attrName; - (void)setValue:(id)newValue forKey:(NSString *)attrName; |
valueForKey: 这个方法允许你通过变量名读取变量的值. 当然, 很可能已经存在一个方法专门用来读取这个变量. 这个方法是这样执行的: 如果存在一个访问方法, 那么就是用这个方法去读取变量值. 如果没有, 那么就直接去读取给定名称的变量.
假设把字符串 @”foo” 传给 valueForKey:.
如果object拥有一个方法 foo, 那么 valueForKey 就会执行这个方法然后返回 foo 的返回值. 如果没有, valueForKey 就开始在object的类变量里面寻找是否有 foo 这个变量. 如果找到了, 那么就返回 foo 的值.
如果object里面既没有 foo 这个方法, 也没有 foo 这个类变量, 那么一个异常就抛出来了.
More