目前开发中,需要借鉴一些做的比较好的网站,这些网站的网页是在移动设备上展示的,用桌面浏览器无法看到。
这里列出3种办法,不全面,只是我现在用到的。这些方法的基本思路是通过设置HTTP头来“欺骗”服务器,让它给出适合移动设备的响应HTML内容。
Chrome加参数
可以使用Chrome浏览器,通过命令行执行,增加一些参数,来模拟指定移动设备。
可以参见这篇文章:http://luckerme.com/archives/903.html
我用的是Mac,这里启动Chrome的命令是:
open /Applications/Google\ Chrome.app –args -user-agent="Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10"
测试了一下:http://ipad.qq.com,正常显示:

能正常显示使用。另外,如果要调整窗口大小,匹配移动设备的分辨率。需要下载插件web developer:
Read more »
iOS屏幕变换,比如从竖屏转为横屏,虽然可以直接使用UIViewController的:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)
但是,因为屏幕变换一般都要在视图(UIView)中处理,这种写法对视图并不方便。
也可以覆盖UIView的:
- (void)layoutSubviews
在该方法中调整自身的frame属性。不过该方法应该是用于对自身的子视图做处理的方法:
Subclasses can override this method as needed to perform more precise layout of their subviews. You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want. You can use your implementation to set the frame rectangles of your subviews directly.
因此,也不适合。
Read more »
这个工具不但好用,而且免费。
如果你使用Mac OSX 10.7,或者10.6的后期版本,应该有App Store。那么安装是极为方便的。

如图所示,直接在search框中输入skitch,就可以找到它,然后安装即可。
以前经常看到使用这个工具截图的图片,这回终于使用到这个工具了。可以看到它有特色的箭头形状。另外,如果用手工画线,它会反锯齿。
iOS开发的时候,经常会用到延时执行,比如:
[self performSelector:@selector(initContentView) withObject:nil afterDelay:2];
在这里会延时2秒执行initContentView方法。
有时候,需要取消延时操作。尤其当这个延时比较长的时候。比如:
- 延时10秒显示一个动画,可未到10秒,用户操作退出了当前的视图
- 演示10秒隐藏当前的工具条菜单,在此期间,又对菜单做了操作,也许只是touch了菜单区域
上述情况,都需要取消延时调用,后一种情况,还需要启动新的延时调用。
解决办法很简单:
[NSObject cancelPreviousPerformRequestsWithTarget:self]
这样就取消了self对象所有的延时操作。
在使用NSOperationQueue简化多线程开发中介绍了iOS的操作队列使用方法。这里补充一下队列的优先级功能。
假设现在队列中有多个操作(NSOperation),现在再向队列中加入新的操作,并且希望新增加的操作排在未执行操作的最前面。这时就需要设置操作的优先级了。
编写了个最简单的NSOperation,头文件:
#import <Foundation/Foundation.h>
@interface MyOperation : NSOperation{
NSString *name;
}
@property (nonatomic,retain) NSString *name;
@end
Read more »
以下内容翻译自:
http://code.google.com/p/cocoaasyncsocket/
CocoaAsyncSocket支持tcp和udp。其中:
- AsyncSocket类是支持TCP的
- AsyncUdpSocket是支持UDP的
AsyncSocket是封装了CFSocket和CFSteam的TCP/IP socket网络库。它提供了异步操作,本地cocoa类的基于delegate的完整支持。主要有以下特性:
- 队列的非阻塞的读和写,而且可选超时。你可以调用它读取和写入,它会当完成后告知你
- 自动的socket接收。如果你调用它接收连接,它将为每个连接启动新的实例,当然,也可以立即关闭这些连接
- 委托(delegate)支持。错误、连接、接收、完整的读取、完整的写入、进度以及断开连接,都可以通过委托模式调用
- 基于run loop的,而不是线程的。虽然可以在主线程或者工作线程中使用它,但你不需要这样做。它异步的调用委托方法,使用NSRunLoop。委托方法包括socket的参数,可让你在多个实例中区分
- 自包含在一个类中。你无需操作流或者socket,这个类帮你做了全部
- 支持基于IPV4和IPV6的TCP流
AsyncUdpSocket是UDP/IP socket网络库,包装自CFSocket。它的工作很像TCP版本,只不过是用于处理UDP的。它包括基于非阻塞队列的发送接收操作,完整的委托支持,基于runloop,自包含的类,以及支持IPV4和IPV6。
Read more »
使用Grails和Groovy,实现了这样的需求:
- zip文件上传
- zip文件上传后,在zip文件中加入自定义文本文件
在Grails实现复杂的数据录入上实现的本示例。示例如图:

准备工作:文件上传
首先说一下文件上传,在Grails中,借助Spring MVC的底层支持,实现还是很容易的。
视图:
<body>
<div style="margin-left: 15px;">
<g:message code="${flash.message}" />
<g:form action="uploadFile" method="post" enctype="multipart/form-data">
<input type="file" name="myFile" />
<input type="submit" value="上传" />
<input type="hidden" name="id" value="1"/>
</g:form>
</div>
</body>
在这里hidden了一个参数,是用于服务器端使用的。
Read more »
多线程开发是一件需要特别精心的事情,即使是对有多年开发经验的工程师来说。
为了能让初级开发工程师也能使用多线程,同时还要简化复杂性。各种编程工具提供了各自的办法。对于iOS来说,建议在尽可能的情况下避免直接操作线程,使用比如NSOperationQueue这样的机制。
可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。
你可以设置线程池中只有一个线程,这样,各个操作就可以认为是近似的顺序执行了。为什么说是近似呢,后面会做解释。
编写最简单的示例
先写个最简单的示例。
Read more »
有这样的需求:

要查出来album_id为1和4的记录,因为它们的tag_id是1和2。
这里需要用到子查询。SQL的写法为:
Read more »
在Grails实现复杂的数据录入示例中,如果删除一个图书对象,而这个对象是另一个或多个对象的相关图书。这时就会报错。
当然,我们可以根据这个异常来提示客户,不能删除,虽然这不是个好方法。但是客户需要知道它到底被哪几个对象关联了。
可以使用hql的join子句实现这样的功能。
这里再把Book实体代码列出来:
class Book {
static mapping = {
//id generator:’uuid.hex’, params:[separator:'-']
//relativeBooks cascade:"delete"
}
static hasMany=[relativeBooks:Book]
//String id
String name
List<Book> relativeBooks=[]
}
Read more »