存档

‘日常’ 分类的存档

loaded the “ViewControl” nib but the view outlet was not set 错误的解决办法

2012年10月10日 没有评论

糗事的 ios 项目最近一直都无法编译运行,因为每次 command+R 的时候都出现了 loaded the “ViewControl” nib but the view outlet was not set  这个错误提示。本来英语就不咋滴,再加上对 xcode 和 objective-c 不熟悉,简直弄昏了头。

后来发现了解决方法,很简单,基本功的问题。

1、先点击 File’s Owner ,然后选择右边的 Identity inspector 选项卡,Custom Class 窗口,Class 文本框里输入 xib 文件的文件名,这里是 ViewControl ,回车。

2、在 File’s Owner 里添加一个 Outlet 到 view 控件。具体方法见上一篇文章

3、重新编译,就可以运行了。

 

原因分析:由于当初新建项目时默认的 View 控件被我给删除了,后来我又添加的一个 view 控件。和新建项目默认的view不一样的地方在于,File’s Owner 的 Class 默认为 NSObject ,所以需要手工修改和当前的nib文件关联。

感觉在学习多视图处理的时候如果不注意应该也会碰到这个问题吧。

分类: iOS, 日常 标签: , ,

Xcode 中插座变量和动作释疑

2012年10月10日 没有评论

几乎在一年前,我的博客里《iOS版本的hello world》是发表的第一篇关于 ios 开发的文章,那只是一个很简单的示例,之后我就在没有再写了。一来是因为我很懒,另外一个很重要的原因就是我被一个问题弄迷惑了。

一年前,我从网上下了几个电子书,晚上躲在被窝里慢慢看。你知道的,现在我几乎很少买书的,这方面的书都太贵了,到后来才买的一本书。正是这书里的内容让我迷惑了很久很久。在  cocoaChina 上看了下,感觉有点高级不太针对入门的人,朋友中也没有人可以问,所以一直在困惑。

我们来举一个例子来说明下,在视图中有一个文本框和一个按钮,点击按钮显示文本框里的内容。要如何实现呢?

1、在 h 文件里添加一个属性,代码为 @property (nonatomic,retain) IBOutlet UITextView *txtInfo;

2、在 h 文件里添加一个动作 -(IBAction) btnClick:(id) sender;

3、在m文件里写实现代码 @synthesize txtInfo;  -(IBAction)btnClick:(id)sender{//这里是具体的点击实现按钮}

在这个时候来运行程序的话,应该是得不到预期的效果,为什么呢?因为还没有把控件和代码变量绑定起来。

接下来是第4步,4、切换到 xib 文件,拖动 File’s Owner 到文本框上去;然后拖动按钮到 File’s Owner 上去。需要注意的是,他们的拖动方向相反,前后并不一致。此时编译运行程序,应该就可以得到预期效果了。

其实第4步操作就是标题所述的绑定插座变量和动作。这个时候,我的疑问就来了。为什么要拖动方向相反呢,我要如何记住拖动的方向呢?

我就一直在纠结,为什么 xcode 不能像 vs 那样友好一些,拖下控件就可以写代码多好呀。

只到上个周末,我突然就明白了,那本书坑爹呀。

第4步是可以用一个方向来完成的,在 File’s Owner 上面点击右键,会弹出菜单。将里面的 + 号拉到控件上去一样第可以实现目的。插座变量,动作都可以用相同的顺序来。其实在 .net 里,是vs帮我们完成了这个绑定的操作。例如:

protected Button btn;  btn.Click+=new btn_Click;  protected void btn_Click(object sender, EventArgs e){}

分类: iOS, 日常 标签: , , ,

vs 2012 中js的intellisense智能提示

2012年9月17日 没有评论

在前面的博客里提及 Visual Studio 2012 RTM 已经出来有一段时间了,在 vs 以前的版本里,对于用户的智能提示做的还不够好,在 2012 的版本里大有改善,今天我们要分享的是如何在  vs 2012 里使用用户 js 的 intellisense 智能提示。

使用起来还是很简单的,比如说项目中有个 common.js 文件,这个时候只需要添加一个名为  common.intellisense.js 的文件就可以了。IDE 可以自动发现,在开始的时候我还不清楚,专门在页面里引用了下,结果运行时总报告错误,后来才发现这个技巧。

场景:在common.js 文件里有一个 load 方法,有2个参数 ,格式如下:

function load(url,charset){}

要实现 intellisense 智能提示,我们只需要在 common.intellisense.js 文件里添加下面的方法即可:

intellisense.annotate(window,{     “load”:function(){
/// <signature>
///   <summary>加载 js 文件</summary>
///   <param name=”url” type=”String”>js 文件的路径</param>
///   <param name=”charset” type=”String”>js 文件的字符编码,例如 utf-8</param>
///   <returns type=”Object” />
/// </signature> }, });

简单地说,我们只需要完善 intellisense.annotate 方法即可,该方法接受 2 个参数,第一个参数为想要进行智能提示的对象,示例中使用的是 window 对象,也可以是其它的对象;第二个参数是一个 json 对象,传递的是智能提示的参数列表。

智能提示以 signature 包含,常见的有 3个,summary 描述的是该方法的功能;param 是具体每一个参数的描述,还可以包括类型;return 是返回类型的描述。从事 C#/asp.net 、Java 的同学看着是不是觉得很熟悉呀~

此时,我们在页面中输入 load 时,就会出现描述的内容,输入参数时,就会提示参数相关的信息,感觉太酷了。

如果我们在文件头添加 reference 引用,就可以脱离上文中 js 代码必须和智能提示文件文件名对应的限制了,例如 /// <reference path=”Scripts/jquery-1.7.1-intellisense.js”/> 。如果你愿意,可以同时引入多个 reference 文件,需要提醒各位的是这里的斜杠可是 3 个哟,不要输入错了。

看起来很简单,对不对。如果有什么问题,快给我留言吧。

在Webform (asp.net)中使用Route 路由之中级实现

2012年9月7日 没有评论

相信经过前面2节文字的介绍,同学们可以快速地实现route路由的目的,并运用在实际的项目中了。在这一节里,我们在讲述一下路由更进一步的实现。

在前面的例子里,我们是把所有的路由信息给放在 Globla.asax.cs 文件里了,这样就产生了一个问题:由于实际业务的变化,每次都需要在该文件里做调整,然后重新编译部署。是不是觉得很麻烦,有没有一种更好的方式,不需要编译是最好啦。

很自然,有经验的同学会想到把路由表放在 web.config 配置文件里,这样的话每次在调整的时候只需要修改 web.config 文件就可以了。我也查询了下网上的资料,由于路由表是一个键值队列,需要在 web.config 里添加自定义节点,并且还需要编写这个自定义节点的实现类。我感觉实现思路有些麻烦,所以下面的一种方式就出来了。

我们把路由表信息放在 xml 文件里而不是 web.config 文件里,即使 web.config 事实上也是个xml。这样做的好处,一来不需要编写自定义节点的实现类;二是把路由表单独抽离出来,避免由于路由表的修改而带来误操作影响全局。

我们新建一个PageRoutes文件,继承 RouteBase 类,并实现其方法。主要有2个方法 GetRouteData 和 GetVirtualPath 。这2个方法是什么意思呢,简单地举例说,如果想从 /u/wave 得到 /user.aspx ,调用的是 GetRouteData 方法,如果是从 user.aspx 里得到 /u/wava , 调用的是 GetVirtualPath  方法。后者在 MVC 里用的非常多,在 webform 中,我这里详细描述 GetRouteData  方法,其它的原理是一样的。

我们来新建一个Route.xml文件用来保存路由信息。
<?xml version=”1.0″ encoding=”utf-8″ ?>
<Route>
<Page virtualPath=”/home” routePage=”~/default.aspx” />
<Page virtualPath=”/about” routePage=”~/about.aspx” />
<Page virtualPath=”/u/{userid}/{noteid}” routePage=”~/notedetail.aspx” />
<Page virtualPath=”/u/{userid}” routePage=”~/notelist.aspx” />
</Route>
接下来,我们把精力放在 GetRouteData 方法上,这个方法会拦截所有的请求,如果没有需要处理的,则返回 null 跳过进行后面的操作。下面的代码有点长,来慢慢地解说,

public IRouteHandler RouteHandler { get; set; }

public override RouteData GetRouteData (HttpContextBase httpContext)         {

string xmlPath = httpContext.Server.MapPath (“~”) + “Route.xml”;

if (!File.Exists (xmlPath)) { return null; } //如果配置文件不存在则直接返回

XmlDocument doc = new XmlDocument ( );

doc.Load (xmlPath);

XmlNodeList list = doc.GetElementsByTagName (“Page”);

string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(1).ToLower();

foreach (XmlNode node in list)          {

string n = node.Attributes[“virtualPath”].Value.ToLower();

//第一步,直接比对,优先级最高

if (n== virtualPath) {

var data = new RouteData();

data.RouteHandler = new PageRoute(node.Attributes[“routePage”].Value);

return data; }

//第二步,带 {userId}的参数比对

string v=n;

string o=new Regex(“{(\\w|\\W)+?}”).Replace(v,”(\\w|\\W)+”);

Regex reg = new Regex(o);

if (reg.IsMatch(virtualPath)){

var data = new RouteData();

data.RouteHandler = new PageRoute(node.Attributes[“routePage”].Value);

string[] a = n.Split(new char[] { ‘/’, ‘.’ });

string[] b = virtualPath.Split(new char[] { ‘/’, ‘.’ });

for (int i = 0, j = a.Length; i < j; i++) {

if (a[i].StartsWith(“{“))  {

string d = a[i].Replace(“{“, “”).Replace(“}”, “”);

data.Values[d] = b[i]; }}

return data; }}

return null; }

程序首先是检查xml文件是否存在,如果存在就加载并生成列表,使用当前的 url 在列表里遍历,如果找到了就返回信息。对于有参数的,则找到参数部分,看是否符合要求,符合的话先把参数填充进去,再返回信息。最后,如果都没有找到,则返回 null 跳过进行后面的。

现在,我们只需要在 Global 文件里添加 routes.Add(new PageRoutes()); 这一行就可以了。以后需要调整的时候直接修改 Route.xml 文件即可。至此,webform 中使用 Route 的文章基本上就写完了。

写在后面的话,其实这么写有一个潜在的性能问题,就是每次访问都需要加载 xml 文件,比较好的实现方式是把请求的路由信息放在缓存里,缓存依赖设置为文件类型的,这样的话每当xml有修改的话,缓存就自动失效重新加载 xml 。这个不是很难,就留给各位同学们去实现了。

而对于 GetVirtualPath 方法,我这里并没有去提及,一是对于传统的 webform 来说,用到的机会比较少;二是需要根据具体的项目来定义,这里以通用例子来讲解有误导嫌疑;三是给大家个锻炼的机会。

祝大家编码愉快。

分类: 日常 标签: , ,

在Webform (asp.net)中使用Route 路由之初级扩展

2012年9月7日 没有评论

在上一节,我们分享了如何实现基本的路由,可以满足很多的场景。

对于asp.net 稍微熟悉的同学一定不会对 Ashx 文件陌生,这是一个只具有代码逻辑的页面,通常用在验证码显示、文件下载等几乎没有用户界面的情况下。我就非常地喜欢使用这样的文件。

有的同学在对这样的文件进行路由的时候,会是这么来写代码,routes.MapPageRoute (“data”, “data”, “~/handler.ashx”); 编译一运行,我瓷熬,居然报错了。报错信息是什么呢?大致是这样的一条错误信息:类型“WebSite.Handler”不从“System.Web.UI.Page”继承。原因就在于常见的 aspx 和 ashx 虽然都实现了 IHttpHandler 接口,但是又不完全一样。

为了解决这个问题,其实这个问题也是我写这几篇文章最初的出发点,网上的代码基本上和上一节的差不多,并没有解决本节的问题。

我们在项目中新建一个类,取名 PageRoute,继承自 IRouteHandler 。在这个类里,我们只需要实现 IRouteHandler 接口就可以了。不多说,上代码。
#region IRouteHandler 成员

public string RoutePath { get; private set; }

public PageRoute (string routePath){RoutePath = routePath;}

public IHttpHandler GetHttpHandler (RequestContext requestContext)
{
if (!RoutePath.Contains (“.ashx”))
{
return BuildManager.CreateInstanceFromVirtualPath (RoutePath, typeof (Page)) as IHttpHandler;
}
else
{
return BuildManager.CreateInstanceFromVirtualPath (RoutePath, typeof (IHttpHandler)) as IHttpHandler;
}
}

#endregion

从代码里,可以清楚地看到,在 GetHttpHandler 方法里分别对 aspx 和 ashx 文件进行了处理,虽然返回的都是 IHttpHandler ,但是在转换的时候,设置的 typeof  是不一样的。

接下来,在 Global.asax.cs 里这么来写 routes.Add (“getdata”, new Route (“data”, new PageRoute (“~/handler.ashx”))); 各位同学们要记住这里的写法和上一节里的写法不一样喔。这样就可以实现对 ashx 文件的路由了,当然对于 aspx 文件,使用2种方式都可以的,例如 routes.Add (“user”, new Route (“u/{userid}”, new PageRoute (“~/userlist.aspx”))); 这样

是不是很神奇呀?

在这一节里,我们就完全解决了传统 webform 的路由实现问题,特别是不从“System.Web.UI.Page”继承这个问题。下一节我们来提一提再高级一点的用法。

分类: 日常 标签: , ,

在Webform (asp.net)中使用Route 路由之基本实现

2012年9月7日 没有评论

路由这个东西其实很早前就出现了,更多的是出现前其它的平台/语言中,对于 .Net 来说比较晚。那时很羡慕只需要在 apache 、ngix 中配置下就可以使用了。

我记得第一次近距离的使用是在门楼网里,那个时候屈屈把 Route 的这部分代码给剥离出来单独给我看过,使用了一个第三方组件,并且需要修改 IIS 的设置才能生效,缺点就是会接管所有的请求包括图片、样式等等。后来把代码消化后,用在了学校的新闻网里,没有想到5年多过去了这部分代码还在继续为师生们服务着。

再后来,微软推出了 MVC,到现在已经是第4个版本了。在 MVC 中,.Net 终于原生支持 Route了,但是在最开始还只是为 MVC 来服务的,网上也很多教程都是针对 MVC 系列的,我们这里就来讨论下如何在 webform 上来实现。

首先,需要在项目里添加 Global.asax 文件,在这个文件里要做的事情就是在应用启动的时候,添加路由注册信息到里面。

protected void Application_Start (object sender, EventArgs e) { RegisterRoutes (RouteTable.Routes);  }

然后在protected void RegisterRoutes (RouteCollection routes){routes.MapPageRoute (“default”, “home”, “~/default.aspx”);}里方法是这样的,什么意思,就是说你访问 /home 的话,路由会直接帮你转向到 default.aspx 页面去。

上面的方式可以满足最基本的需求,可是事实上很多情况下,url 地址里是有带有参数的,如何提交参数呢。可以这么来,routes.MapPageRoute (“notedetail”, “note/{userid}/{noteid}”, “~/note.aspx”); 从代码里可以发现,url 里附加了2个参数,分别为 userid 和 noteid ,它们用大括号给括起来了。看起来是不是有点像存储过程里的参数呢,哈哈。这个冷笑话一点都不好玩。

回到正题,再添加了上面的代码后,如果用户访问 /note/wave/1346 ,那么会被路由到 note.aspx 这个页面里去,在页面里接收参数可以这么来使用 string userId=Page.RouteData.Values[“userid”]; 就不再是传统的 QueryString 方法了。

至此,我们就实现了在 webform 中使用 Route 的基本功能呢了。下一节,我们来进行扩展。

分类: 日常 标签: , ,

小事故,丢人啊。

2012年8月20日 没有评论

昨天不小心出了点事故,骑自行车加速时把 olay 给弄掉下去了。

怎么说呢,我从学骑自行车开始,一次是小时候从墙壁险擦过去,一次是2、3年前某个雨夜摔了一下。应该算是幸运的,可是昨天把人家给弄得掉下去了。分析来看,应该是在加速的时候,车子摇摆,重心不稳,人家没有坐好结果就掉下去了,但是掉了一半似乎又被什么给挂住了,在地上给拖了一下。

当机立断,立马把车子给扔了,小腿被踏板给撞了下,一瘸一瘸地跑过去。左边胳膊和腿都擦伤了,雨伞也坏了,衣服倒还没有擦破。

回家后擦酒精,上碘酒。

真丢人啊,路面平坦的很。自己骑车给弄成这样。该怎么赔偿就怎么赔偿吧,诶哟喂。

分类: 日常 标签: ,

北京下大雨

2012年7月23日 没有评论

上周六的时候,去了一个叫做洼里乡居楼的地方吃饭,那是一个类似农家乐的地方。从地铁出来,开始找郊100的站台,后来没找到,于是手机搜索其它的路线,好在有个945路公交。坐到大柳树(环岛)下车,又找了个麻木,给送到乡居楼,20块钱。这个麻木师傅还不错,挺能说的,约好了回程的时候也去找他。那个郊100,真是见鬼去吧,百度地图这次不靠谱呀。

话说在公交上,我有看到航空博物馆,前几天在马蜂窝上也看到有这个景点的,说是门票80一张,下次有机会我要去航空博物馆看一看。

到乡居楼的时候就已经开始在下雨了,里面吃饭的人不算很多,不过也不少。听麻木师傅说如果是晴天,这里吃饭都得排队。那个什么鸡肉分量很足,其它的一般般。吃饭完,就四处晃荡,看到他们自己的养鸡场,北京油鸡是98块一只。市场里活鸡估计也就20、30的样子吧。

简单看了下地图,往游乐园方向去。门票一个人是20块。进去后,首先就是过独木桥啊,爬木墙啊,荡绳啊什么的,主要是下雨天,简单地玩了下,就开始下一波。在路上有看到行人拿的荷叶,很久没有看到自然状态的荷叶了,心里还在琢磨是哪里来的。不久就来到了那个池塘,池塘里还有几个小木舟。水边的荷叶都被摘光了,费了好大功夫摘了个荷叶。

正往前走,雨就开始下大了,恰好荷叶可以排上用场。看到有个乡村动物园,就去瞅了一眼。什么骆驼、牦牛、兔子、鹅、野猪、牧羊犬、山羊、松鼠、鸭子、鸵鸟、澳洲鸵鸟、鸽子、梅花鹿、野鸡……其它的不记得了。

雨越下越大,看到旁边有温棚,就赶紧跑进去,原来是个类似盆景展览的地方。一时也走不了,就在一起打了几圈斗地主。雨是越来越大,这个温棚开始漏雨了,地面都开始漫水了。我们又换了个温棚,恰好是个西红柿采摘的,我们就进去了,一边摘一边吃,最后买了几斤。注意喔,西红柿可是8块钱一斤咯,相对市场可是贵了很多。

买了西红柿我们就直接出来了,那什么西瓜采摘、游乐场什么的都没有过去,只去了一半的面积吧。打电话叫上午的麻木师傅过来接我们去坐公交,这个时候我已经湿身了。在公交上我把T恤给脱了,盖在前胸,一路到地铁。

出了地铁,雨下的更大了。狂奔回家,小区里都是水,快到膝盖了。我相信很多别的地方应该也是这样的。

回家,喝几大口白酒,洗热水澡,煮可乐姜汤。好在没有感冒,但是目前我还不知道是否会落下什么后遗症。

好在第二天是个晴天,去了后海晃了一圈,走的累死了。

分类: 日常 标签: , ,

糗事1.3.4新版本发布

2012年7月9日 没有评论

糗事的这个版本拖了起码有个4个月了,一直都没有更新功能,这个周末给弄出来了。我在各个后台上传新版本时遇到各种奇怪问题,进入后台里面居然显示的是别的开发者的内容。

好在从上个版本开始,我为程序添加了自动更新功能,可以先走程序的更新功能。数据报表情况要等到明天才可以看到。

看到@屈屈 和 @welefen老六 都换 iPhone平台了,看来这糗事的 iOS 版本也得加快进度了。

分类: 日常 标签: ,

控制面板设备和打印机选项卡无法打开解决方法

2012年7月1日 没有评论

这周五上班的时候,走的比较急,公交卡和鼠标都忘记在家,在路上想起来,幸好单位放了N久前买的 罗技M555b蓝牙鼠标。

到单位使用的时候,发现无法连接配对,从托盘区域点开蓝牙,选择 显示 Bluetooth 设备,然后无法打开,刷进度条很慢,到98%的样子就会一直停留在那里。以前鼠标明明是可以使用的。

干活重要,好在单位还有台式机可以使用,就把这事情放下来了。

后来无意间发现需要在服务里启用 Bluetooth Support Service 这个服务的,启用后就可以顺利打开设备和打印机选项卡了。

不过我最原始的问题依然没有解决,蓝牙鼠标还是发现不了,魅族M9也无法通过蓝牙发送文件,iPhone4 蓝牙也配对不了,按照网上的说法,选择属性,去掉 wireless iAPI 没有效果,报告找不到元素错误。

分类: 日常 标签: