换controlcreator owner 权限之后测试是不是要重新做

实验1_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
上传于||暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩5页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢【新朋友】点击标题下面蓝字「皮鲁安全之家」关注【老朋友】点击右上角,分享或收藏本页精彩内容【公众号】搜索公众号:皮鲁安全之家,或者ID :piluwill前言最近不知为何掀起“黑百度”风,360老总不顾颜面微博喊话李彦宏,广大用户纷纷吐槽百度杀毒的静默安装、卸载不了以及软件捆绑安装。这些所谓安全软件的问题也不是一天两天了,之前就有人说某安全软件上传工程源码以完成所谓“云查杀”,又时不时涉嫌各种隐私问题,不一而足。之前在百度杀毒那边实习过一阵,感觉软件不至于无耻到网上所流传那种地步。这里我选择不同平台安装不同的百度产品,从安装到运行,以及卸载,看看它们到底多流氓。工具VM虚拟机、win7 x86、win7 x64、ProcessMonitor、ProcessExplorer、PCHunter、Windbg、VKD百度高速下载百度搜索某软件,会有“高速下载”选项,我们使用高速下载来作为测试:高速下载得到一个exe:npp.6.6.9.Installer_13478_BDdl.exe,图标是度熊手;普通下载得到的是:npp_V6.7_Installer..exe。从文件名可以目测出两个问题:1、高速下载得到的是捆绑了百度产品的2、高速下载得到的是低版本的。可能捆绑是需要时间的吧。那我们运行这个高速版看看会发生什么:首先映入眼帘的是百度下载助手的安装程序,百度的签名:然后下载助手安装成功,并启动notepad++的下载和安装。所以说之前那个npp.6.6.9.Installer_13478_BDdl.exe纯粹是混淆视听,就是baiduxiazaizhushou.exe,怪不得连图标都没变。再试几个其他的高速下载,都是会安装“百度下载助手”,然后再“高速”下载该软件。何来点了高速下载就会静默安装百度杀毒和百度卫士?这里黑得不漂亮啊!不过这个确实也属于欺骗用户的。倒是有时候下载的时候有个选项“安装百度杀毒”,默认是勾选的,如果不取消选择,那铁定是要中招了。我之前确实见过这种情况,不过写这篇文章测试的时候一直没搜出来,只好作罢。另外有一点我觉得是无脑黑,说什么百度搜索360会被屏蔽云云,可能纯粹是网络问题吧。百度说点竞争对手坏话倒有可能,大家都这样,不至于屏蔽竞争对手。我倒是觉得软件中心挺好,起码点下载就是下载,不至于点下载给你安装个美图秀秀;而且也过滤了一些不良软件。这些进步是应该看到的,大家互相黑的同时也在一定程度上互相促进了,对用户来说是好事。这个小问题解决之后我们看看百度杀毒和百度卫士有多少干货。百度杀毒下载百度杀毒最新版,安装并监控。我记得上次我装的时候确实什么都没提醒就装上了,这次测试的时候倒是提醒了。安装之后运行了这两个程序,可以看出一个是主防一个是杀毒服务:PCHunter可以看到百度杀毒装的驱动:有bd0001~bd0004、文件系统过滤、沙箱、反病毒等,驱动还是不少,感觉有点乱。毕竟是内核层的,搞这么多东西难免会出问题。注册了一些系统回调,用于监控进程创建、线程创建、模块加载、注册表更改、关机等,也是一些常规的回调,具体效果得看实现如何。也往往是干掉防护的突破口:Bd0003还有一个DPC定时器:0x8777DFB000x9875DE60C:\Windows\system32\DRIVERS\bd0003.sys文件系统过滤驱动BDFileDefender和BD0003也是实现了一些常规的IRP过滤:这个时候出了个意外,蓝屏了,windbg及时捕捉:
CHKIMG_EXTENSION: !chkimg -lo 50 -d !nt
83e8b3e9-83e8b3f0
8 bytes - nt!KiFastCallEntry+e9
[ 8b fc 3b 35 1c 07 fb 83:e9 f0 02 01 0b 90 90 90 ]
83eafb5f - nt!SwapContext_PatchXSave+2 (+0x24776)
83eafdad - nt!EnlightenedSwapContext_PatchXSave+2 (+0x24e)
83eb7ce0-83eb7ce3
4 bytes - nt!KiServiceTable+5f0 (+0x7f33)
[ e1 42 0d 84:72 97 21 92 ]
4 bytes - nt!PsOpenThread+20f
[ 88 c3 03 00:59 ae 21 23 ]
840a9b80-840a9b83
4 bytes - nt!NtTerminateProcess+43 (+0x22eed)
[ 81 25 fc ff:cc 87 1f 23 ]
840bc935-840bc938
4 bytes - nt!NtTerminateThread+51 (+0x12db5)
[ cc f7 fa ff:17 5a 1e 23 ]
840c0dfe-840c0e01
4 bytes - nt!PsOpenProcess+22d (+0x44c9)
[ 1d 22 00 00:ee 0c 1e 23 ]
840c411f-840c4122
4 bytes - nt!NtDuplicateObject+5d (+0x3321)
[ e2 7f fa ff:0d dc 1d 23 ]
34 errors : !nt (83e8b3e9-840c4122)
FOLLOWUP_NAME:
MachineOwner
MEMORY_CORRUPTOR:
PATCH_bd0001
FAILURE_BUCKET_ID:
MEMORY_CORRUPTION_PATCH_bd0001
BUCKET_ID:
MEMORY_CORRUPTION_PATCH_bd0001
Followup: MachineOwner
---------可以看到bd0001对ntoskrnl进行了patch,具体看看:kd& !chkimg !nt34 errors : !nt (83e8b3e9-840c4122)kd& ln 83e8b3e9(83e8b300)
nt!KiFastCallEntry+0xe9
(83e8b480)
nt!KiServiceExikd& u 83e8b3e9nt!KiFastCallEntry+0xe9:*** ERROR: Module load completed but symbols could not be loaded for bd0001.sys83e8b3e9 e9f002010b
bdde (8ee9b6de)83e8b3ee 90
nop83e8b3ef 90
nop83e8b3f0 90
nop83e8b3f1 0f832e020000
nt!KiSystemCallExit2+0xa5 (83e8b625)83e8b3f7 f3a5
rep movs dword ptr es:[edi],dword ptr [esi]83e8b3f9 f6456c01
byte ptr [ebp+6Ch],183e8b3fd 7416
nt!KiFastCallEntry+0x115 (83e8b415)百度杀毒的驱动对KiFastCallEntry进行HOOK,这是系统入口点,所有系统调用都会经过这个函数。我们需要了解一下系统调用的基本知识,应用层的API做一些参数检查工作之后会调用ntdll.dll的同名nt函数,比如CreateFile会调用ntdll.dll中的NtCreateFile函数(和ntdll.dll的ZwCreateFile完全一样),然后NtCreateFile填写参数之后执行sysenter或int 0x2E,这个时候由应用层进入内核层,内核分发函数就是KiFastCallEntry,它会根据应用层调用去执行SSDT的相应函数。所以KiFastCallEntry是防护软件绝佳的HOOK地点。最早应该是360发现的,所以360使用的HOOK点是最佳的,百度这里看到有nop填充,估计也是无奈之举。同时也能知道百度采用的是比较流行的驱动框架模型,bd0001是个驱动框架,其它驱动通过bd0001的接口注册回调,bd0001调用实现监控。再回头看这个蓝屏:kd& kbChildEBP RetAddr
Args to Child
a39a250c 83f24e71 fa590e4
nt!RtlpBreakWithStatusInstructiona39a255c 83f03 0d3adbc nt!KiBugCheckDebugBreak+0x1ca39a2920 83ecd8e3 d3adbc
nt!KeBugCheck2+0x68ba39a29ac 83e8e5f8 d3adbc
nt!MmAccessFault+0x106a39a29ac ad3adbc
nt!KiTrap0E+0xdcWARNING: Stack unwind information not available. Following frames may be wrong.a39a2a4c a72825cd a5d3ad90 a0020 PCHunter32ag+0x52e2fa39a2af8 aa0
PCHunter32ag+0x545cda39a2b0c a008f1
PCHunter32ag+0x548f7a39a2bfc 83e844bc b0 PCHunter32ag+0xc14 84085eee ba0 nt!IofCallDriver+0x63a39a2c34 840a2cd1 00 nt!IopSynchronousServiceTail+0x1f8a39a2cd0 840a54ac b0 nt!IopXxxControlFile+0x6aaa39a2d04 83e8b42a 00 nt!NtDeviceIoControlFile+0x2aa39a2d04 76fc64f4 00 nt!KiFastCallEntry+0x12a 76fc4cac 00000 ntdll!KiFastSystemCallRet001266dc 00 ntdll!NtDeviceIoControlFile+0xcIofCallDriver用于发送Irp,之后的栈就出问题了,reactos中看实现:NTSTATUSFASTCALLIofCallDriver(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp){
return DriverObject-&MajorFunction[StackPtr-&MajorFunction](DeviceObject,
Irp);}看来是bd0001的分发函数调用出了问题。这个蓝屏纯属意外,恰好可以讲解一下百度杀毒的驱动模型和HOOK技术。现在回归主线。重启电脑。看一下大家比较关心的隐私问题,看看网络链接情况:Baidusdsvc.exe是和220.181.112.254的80端口保持通信的,该IP是北京电信的。Wireshark看一下通信内容,没发现往上传文件的情况。
再看看启动项:
这只是可执行文件和服务,看看驱动:挺多,大部分启动类型都是1,连bd0001都是1,也就是普通驱动,而不是BOOT型。BOOT型驱动启动类型为0,由winload.exe加载,和ntoskrnl.exe以及hal.dll同级,加载时间非常早;之后才加载系统级驱动。所以说如果中病毒了,而该病毒有个boot型驱动,用百度杀毒显然是无能为力的。百度杀毒卸载问题好多朋友都问我如何卸载百度杀毒,真有那么难以卸载吗?这里测试一下。卸载过程真是…… 把“不卸载”大写并且突出,“继续卸载”扁平化恨不得凹进去。不过识字的应该都能顺利卸载完成。接着重启。
没了。目测是卸载干净了。看了看注册表,bd0001等驱动都没了。看一下KiFastCallEntry等HOOK点:kd& !chkimg nt14 errors : nt (83e873e9-83eb3ce3)kd& ln 83e873e9(83e87300)
nt!KiFastCallEntry+0xe9
(83e87480)
nt!KiServiceExitkd& u nt!KiFastCallEntry+0xe9nt!KiFastCallEntry+0xe9:*** ERROR: Module load completed but symbols could not be loaded for bd0001.sys83e873e9 e9f0e29215
bdde (997b56de)83e873ee 90
nop83e873ef 90
nop83e873f0 90
nop83e873f1 0f832e020000
nt!KiSystemCallExit2+0xa5 (83ef7 f3a5
rep movs dword ptr es:[edi],dword ptr [esi]83e873f9 f6456c01
byte ptr [ebp+6Ch],183e873fd 7416
nt!KiFastCallEntry+0x115 (83e87415卧槽,居然还被HOOK呢。
看一下KiFastCallEntry等HOOK点:kd& !chkimg nt14 errors : nt (83e873e9-83eb3ce3)kd& ln 83e873e9(83e87300)
nt!KiFastCallEntry+0xe9
(83e87480)
nt!KiServiceExitkd& u nt!KiFastCallEntry+0xe9nt!KiFastCallEntry+0xe9:*** ERROR: Module load completed but symbols could not be loaded for bd0001.sys83e873e9 e9f0e29215
bdde (997b56de)83e873ee 90
nop83e873ef 90
nop83e873f0 90
nop83e873f1 0f832e020000
nt!KiSystemCallExit2+0xa5 (83ef7 f3a5
rep movs dword ptr es:[edi],dword ptr [esi]83e873f9 f6456c01
byte ptr [ebp+6Ch],183e873fd 7416
nt!KiFastCallEntry+0x115 (83e87415卧槽,居然还被HOOK呢。
试着删除bd0004,禁止删除,应该是下载助手。卸载百度下载助手之后试试。删除成功, 重启看看: kd& !chkimg nt
2 errors : nt (83ebbb5f-83ebbdad)这次没问题了。为什么卸载之后bd0001还会加载到内存呢?可能是我操作有误,重新试了一次发现安装——重启——卸载——重启之后,系统是干净的,没有出现卸载问题。卸载问题是怎么来的呢?考虑到推广,可能是被绑定软件搞的鬼。我们下载一个合作软件,通过绑定方式安装杀毒,看看卸载情况。不得不说,百度的情况肯定是被水军和职业黑夸大了,我找了好久都没找到绑定的情况,即使安装百度输入法并且一路下一步,都没能被绑定装上杀毒。X64情况Windows 64位对内核采取了一系列保护措施,最经典的就是KPP和DSE,Kernel Kernel Patch Protection主要使用PatchGuard,禁止修改内核,所以传统的SSDT Hook和修改内核对象等手段都走不通了;DSE强制驱动签名。所以64位驱动大多是使用windows官方定义的回调,结合应用层HOOK来搞。64位win7上装好杀毒,看了看services,跟32位的差不多,也是bd00001等系统级驱动。运行卸载程序之后重启,并没有发现不能卸载的情况。感觉非常不好,测试了半天连个流氓行为都没有捕获。难道那些流言都是空穴来风?问题复现测试了半天,没发现百度杀毒有问题。问了一些出问题的朋友,有的说是捆绑情况,杀毒、卫士、浏览器同时被装上,然后卸载重启之后右下角弹框,点修复就会重新装上。之前的测试只是针对百度杀毒一个,这次把杀毒、卫士都装上试试。官网直接下载某个非常小的下载器。会把最新版杀毒卫士都下载下来然后安装好。这个过程中确实没有任何提醒,没有下一步,直接就装好了,连安装地址都不能选择。PCHunter看了一眼吓一跳,能装的都装上了:驱动也多了几个:多了一些网络过滤驱动和浏览器防护的,这也是卫士的基本功能。其他的HOOK就不看了,都差不多。还是关注一下卸载问题。卸载百度杀毒,同时删除配置信息,重启。百度卫士修复了半天漏洞,优化这个那个的,反正界面很华丽得搞了半天。百度杀毒确实是卸载掉了。那么怎么样才能重现卸载不了的问题呢?我查了一下百度流氓行为的一些信息,按照他们说的某个软件,都测试过一次,均没有出现不能卸载这种奇葩现象。有一种情况是可能的,装百度杀毒和百度卫士,但是只卸载其中一个,另一个使用猥琐的方法(比如在修补漏洞界面非常隐蔽的隐藏一句同时安装杀毒/卫士)骗取用户同意然后重新安装另一个。驱动公用,想装另一个太容易了。另外我绝对不是托儿,首先我还不够资格;其次也没必要,我只是想亲自看看传说中的流氓行为,只不过搞了半天没有复现,仅此而已。杀软这种东西很大程度上是给小白用户个心理安慰,真正能有多大用呢?当然升级软件方便一些,清理垃圾也方便一些,沙箱针对一般恶意应用也提供了足够防护。各家厂商技术差距肯定存在,但是那些技术的差距落实到每个用户电脑上,又能有多大的体现?大佬们口水仗打得爽,跟用户其实没半毛钱关系,难不成你还真以为公司没事儿干为了情怀做个杀软让你用?装软件的时候也非常注意是不是捆绑了其他程序,多长个心眼儿,那些传说中的流氓行为都可以避免。现在最大的问题是法律法规对互联网行为没有做好规范,这个黑那个,那个黑这个,真正为用户考虑的没几个,号称为用户考虑也不过是宣传口号而已。真希望能早日做到有法可依。[作者/dedogger,作者独立观点,FreeBuf不做任何形式背书。本文属FreeBuf黑客与极客]回复获得以下图文等信息论坛可进入微论坛畅谈任意官方机器人陪聊首页查看技术文档(逐步更新中)留言进入留言板相册国内外大牛真容皮鲁安全之家(piluwill) 
 文章为作者独立观点,不代表微头条立场
的最新文章
美国华盛顿大学专家警告称,黑客可将图片插入恶意软件中,使用脑机接口技术(BCI)记录人类下意识的反应沉寂已久的CVE-漏洞挂马忽然“重出江湖”,全国有数十款软件和网站出现此漏洞挂马攻击,其中还包括用户量上亿的音乐播放器软件。据英国《每日邮报》报道,在神秘的黑洞背后一直存在着一个非常神奇的研究领域,科学家们也将它称之为“引力奇点”。本周在拉斯维加斯参加黑帽大会的网络安全研究人员萨尔瓦多·门多萨(Salvador Mendoza)指出,三星电子移动支付功能Samsung Pay的安全存在局限性。如果黑客发现了这一漏洞,可以通过另一部手机完成欺诈性付款。“催眠”特斯拉,这样疯狂的事情,也许只有在世界顶级黑客会议 DEF CON 上才能看到。而且,没错,又是中国黑客干的。
先来说说特斯拉辅助驾驶(AutoPilot)。这个让埃隆·马斯克引以为傲的系统,已经在全世界的特斯拉汽车上大规模应用。一不小心,你的电话、微信连同自己正在关心的疾病都一起被泄露了那些对你的隐私感兴趣的民营医院。据PCWorld报道,近日以色列大学研究成果表明,通过机械硬盘噪音磁盘信息也可能会被窃取。超过60个未公开的漏洞影响22个家里路由器(SOHU路由器)游戏被纳为体育课程的一种,课程编号为PE-6 #25718 Walking。完成该课程的学生可获得一个学分。说到防弹衣相信大部分人都不陌生,然而有部分人至今仍然认为防弹衣里面是装有钢板的,虽然最初的防弹衣确实如此,但是随着科技的进步防弹衣里面的材质早已更新换代,今天我们就来揭秘一下防弹衣里面到底藏着什么!近日安全研究者找到了一种方法,可以远程控制所有三星智能手机(包括galaxy s7和galaxy note7),并恢复出厂设置。单从手机来看,锤子手机只能算是一款合格的国产手机,有自己的特色,但功能性能、工艺水准、返修率等都没有特别过人的地方。WEP是最初开发的保密协议,叫“有线等效保密”它使用了“RC4的RSA”算法,它的加密过程中有两个部分比较重要,一部分是24位的初始化向量IV,另一部分就是用户密钥。如今手机已经成为人们生活中重要的组成部分,除了内含大量个人隐私之外,手机还充当了钱包的角色,丢了可不是小事。美国FireEye报告称,中国一可能有政府背景的黑客组织在亚洲长期从各机构窃取信息凯尔o利明(Cal Leeming)曾告诉我许多关于银行安全漏洞的可怕事情,然而上面这句话让我尤其难以忘怀。他并未称自己是一名黑客——尽管他几乎是人们对黑客固有印象的完美化身。Facebook CEO的技术大牛扎克伯格居然着了黑客的道,他的Twitter和Pinterest账号双双被攻破,如果你认为这黑客是位“扫地神僧”,那就错了,扎克伯格被黑是因为用了超级简单的“dadada”做密码。经常刷朋友圈的你是否发现,有些人发的照片总是非常清晰,而自己发的照片一上传就变模糊,这到底是回事呢?美国联邦调查局(FBI)局长詹姆斯o科米(James Comey)今天在伦敦举行的阿斯彭安全论坛上暗示称, FBI为解锁加州圣贝纳迪诺枪手Syed Rizwan Farook 的iPhone至少花了130多万美元中国黑客成长于充盈着激情与理想主义的年代。在新的世界,黑客们最终与现实妥协黑客组织Anonymous组织采用了一系列简单的技术方法和社会工程学来攻击安全技术公司HBGary Federal公司的网络,这其中涵盖的很多网络技术问题都值得其他网络安全专家借鉴。【新朋友】点击标题下面蓝字「皮鲁安全之家」关注【老朋友】点击右上角,分享或收藏本页精彩内容【公众号】搜索公众7个小技巧,提升你的wifi信号,绝对新技能,赶快get吧!在那个年代,大多数组织在他们的内部网络与互联网之间,只有一道防火墙。随着时间的推移,重心开始转移,互联网攻击逐渐变成一种对网络罪犯而言,有利可图的商业。谷歌Play商店预计将会在3月份回归中国,届时谷歌商店与服务都会推出中国版本,帐号方面与国际版不会互通,后期在大陆销售的机器应该都会含有Google服务中国版。小时候,安全软件是一只小小的狮子,你不管它,它打呼噜。
长大后,安全软件是右下角关不掉的弹窗,不装开机 20 秒,装了 3 分 20 秒。有研究证明,Anonymous黑客团体的规模比人们的预期要大的多,并且正在成为全世界范围内最流行一群人。每天,科技领域的公司都在尝试将一个家中物体连接到因特网。其中一个互联网连接的家用设备就是智能门铃。我们每个人都是与众不同的,拥有个人所独有的长处、弱点和个性。虽然这些是我们每个人都清楚的,但是我们却难以了解这种特性是否或者说如何反映在大脑活动中。域名劫持是互联网攻击的一种方式,通过攻击域名解析服务器(DNS),或伪造域名解析服务器(DNS)的方法,把目标网站域名解析到错误的地址,其效果就是对特定的网址不能访问或访问的是假网址。最近黑产利用腾讯邮箱的漏洞组合,开始频繁的针对腾讯用户实施攻击。
其利用的页面都起名为godlike.html,所以我们把这起攻击事件命名为godlike如果你曾经对一个移动应用进行渗透测试,并且如果这个应用有很好的安全性,你会发现它不会允许你拦截它的流量,并且会发动中间人攻击来抵御路由器使用者往往会因为步骤太过麻烦,以致干脆不做任何加密安全设定,因而引发许多安全上的问题。WPS用于简化Wi-Fi无线的安全设置和网络管理。NASA科学家从太空的角度,分析并对比了北京,洛杉矶和亚特兰大三地的空气质量,什么是雾霾?为什么中国空气污染这么严重?以及美国空气污染的历史,解决办法,以及现状。如果你有空余的时间,为什么不尝试像Bob Clagett一样制作一把超大款的星战“光剑”,不过即便如此,像Bob Clagett弄得这么大的光剑可真是绝无仅有。瞻博网络公司销售的防火墙产品中发现重大漏洞,可被用于监测安装该系统的数据。本周最近曝光的机密档案显示,美国国安局NSA曾协助英国GCHQ(政府情报机构)的间谍利用瞻博网络防火墙产品中获取情报。渗透,顾名思义已经获取到目标的部分权限,需要进一步扩大战果了,这里会遇到各种各样的问题,比如信息收集,比如目标的查找,比如文件下载的方式,比如等等目前在圣诞节期间威胁到了微软和索尼线上游戏网络(Xbox Live和PlayStation Network)的Phantom Squad黑客团体,其某个主账号已经被社交平台Twitter给停用。一直到现在,科学家们还在尝试着发现一直将那些被称为智能手机的微型计算机放在口袋里的潜在负面影响,智能手表、健康追踪器(Fitness Tracker)等腕带和臂章设备有可能被攻击者用来监视你;此外,通过智能手表中内置的运动传感器,攻击者能够通过受害者手部运动数据来猜测用户向键盘上输入的数据。瞻博网络公司销售的防火墙产品中发现重大漏洞,可被用于监测安装该系统的数据。本周最近曝光的机密档案显示,美国国安局NSA曾协助英国GCHQ(政府情报机构)的间谍利用瞻博网络防火墙产品中获取情报。随着智能手机和平板电脑等移动设备的普及,我们的工作和娱乐都发生了很大的改变,在这样的情况下,WiFi 也变得越来越重要,也有越来越多的人深刻体会到了“没有WiFi不幸福”的感受。最近,一项 Ponemon 实验显示,如果一些技术并不高的白帽子冒充目标政府或者企业的临时工,那么他们也有百分之九十的可能性能够得到许多内部机密文件。NASA科学家从太空的角度,分析并对比了北京,洛杉矶和亚特兰大三地的空气质量,什么是雾霾?为什么中国空气污染这么严重?以及美国空气污染的历史,解决办法,以及现状。目前在圣诞节期间威胁到了微软和索尼线上游戏网络(Xbox Live和PlayStation Network)的Phantom Squad黑客团体,其某个主账号已经被社交平台Twitter给停用。当用户被弹出包含漏洞挂马的广告页面时,会触发网站上的漏洞攻击代码,可能导致用户电脑被安装恶意程序,并受到恶意程序控制, 包括同时“被安装”数十款流氓软件。黑客组织通过 QQ 盗号木马,盗取受害者账号及密码。此次事件受害机器数量颇多,波及范围已达 25 个省市以上,并且情况仍在持续恶化中。通信加密技术一直以来对于美国政府监控恐怖活动来说,无疑是一道巨大的阻碍。在发生巴黎以及加利福尼亚的恐怖袭击事件后,这个问题再一次引起美国政府的重视。事情是这样的,有人在微信朋友圈发起挑战,图片给出两套牌(上图),上面是地主,下面是农民,规则如下:我(发起者)是地主先出4,你(挑战者)是农民,注意不能三带一,如果我赢了你给我红包,如果你赢了我给你红包。本文我们将复制一项技术,我们曾用它来追踪一个叫做Hammertoss的复杂俄罗斯恶意软件,该恶意软件的创造者滥用知名网站(比如twitter和github)来跃过防火墙和躲避追踪。piluwill关注网络安全,提升个人防护能力。本公众号承诺:绝不用危言耸听、哗众取宠的标题,绝不像大多数公众号造谣传谣、永远不会像大多数公众号那样,用造谣无知的内容去拉低您在朋友圈的智商。热门文章最新文章piluwill关注网络安全,提升个人防护能力。本公众号承诺:绝不用危言耸听、哗众取宠的标题,绝不像大多数公众号造谣传谣、永远不会像大多数公众号那样,用造谣无知的内容去拉低您在朋友圈的智商。trackbacks-0
/Program/IOS/802.shtml
写一个iPhone应用程序,要求可以输入名字,点击按钮后,会显示一段文字向输入的名字打招呼,例如输入&宝玉&,显示&你好,宝玉!&
这是一个很简单的应用程序,包含一个文本输入框,一个文本显示框,一个按钮。输入名字到文本输入框,再点击按钮,这时文本显示框的文字就会变成&你 好,&名字&!&。但是要注意,如果用户输入为空,要有警告提示用户重新输入;如果用户输入文字太长,超过16个字符,要自动截断。
根据项目需求,画出相应的产品原型图:
初始时,文本输入框为空,但是显示水印,提醒用户可以输入姓名。文本显示框文字为空。
输入名字并点击按钮后
输入名字,并点击按钮后,屏幕中间显示文字:&您好,&名字&!&。
没有输入名字的警告提示
如果没有输入名字,点击按钮后弹出警告窗口,提醒用户输入名字。
这是一个非常简单的应用程序,实现思路不不算复杂:
一个文本输入框,用来输入文字,需要限制最大字符长度为16个字符,输入框没有内容时,显示水印文字。UITextField控件正好可以满足需求。
一个文本显示框,用来显示最终生成的文字。使用UILabel控件即可满足需求。
一个按钮,点击后,获取文本输入框文字内容,生成&你好,&名字&!&文字,并显示在文本显示框中。如果点击时文本输入框文字为空,弹出警告提示框。
同时,这个应用程序在开发过程中,需要应用到iPhone开发中一些常用的设计模式:
委托(Delegate)
模型 视图 控制器(MVC)
目标 - 动作(Target-Action)
委托(Delegate)
委托模式是一个对象周期性地向被指定为其委托的另一个对象发送消息,向其请求输入或者通知某件事情正在发生。该模式可替换类继承来对可复用对象的功能进行扩展。
在本项目中,应用程序对象会向其委托发送消息,通知它主要的启动例程已经完成并且定制的配置可开始执行。为了建立并管理视图,委托会创建一个控制器实例。另外,当用户点击Return按键后,文本字段也会通知它的委托(即所创建的控制器对象)
委托方法通常会集中在一起形成一份协议。 一份协议基本上就是一个方法的列表。如果一个类遵循某个协议,则它要保证实现协议所要求的方法(有些方法可选择实现与否)。委托协议规定了一个对象可以发 送给委托的所有消息。例如常见的有:UITextFieldDelegate, UIApplicationDelegate, UIScrollViewDelegate, UITableViewDelegate, UIWebViewDelegate。
模型 视图 控制器(MVC)
MVC模式将应用程序中的对象设定为三种角色:模型角色(Model)、视图角色(View)和控制器角色(Controller)。
模型对象(Model)表示数据。例如,在iPhone自带的通讯录应用中,联系人是模型对象,在一个绘画应用中,圆形、矩形是模型对象。
本项目的应用程序用到的数据非常简单&&字符串,并且该字符串只有在按钮点击的方法中用到。其实换一种角度来说,字符串也是一种最简单的模型对象,在其他的应用程序中,模型对象将会更加复杂,并且模型对象在程序中无处不在,可以在多个地方进行访问。
视图对象(View)负责显示数据,比如UILabel可以显示文本、UIImageView可以显示图片,也会支持用户对数据的编辑操作,例如UITextField可以支持用户输入。
在我们接下来要创建的项目中,需要一个主视图来包含其它几个视图&&首先是一个文本输入框,它用于捕获用户输入信息;然后是一个文本显示框,它用于显示文本,而文本内容则是基于用户的输入;另外还需要一个按键,让用户可以点击它,点击后通知文本字段更新。
控制器对象(Controller)介于模型和视图之间。
在我们接下来要创建的项目中,当用户点击按钮后,触发更新操作,控制器对象将会从文本输入框中获取输入的文字内容,并把文字存放在一个字符串中,然后再把文本显示框的内容更新成格式化好的内容。
结合MVC模式,对于本项目的主要流程,整个如图所示:
目标 - 动作(Target - Action)
目标-动作机制,允许一个控件对象(例如按键或滑动条) 向另外一个对象发送一条消息(即动作),以之作为对某个用户事件(例如一个点击事件)的响应。接收到消息的对象则可以对消息进行响应,并针对业务要求做出处理。
在本项目中,当点击按钮时,它会通知控制器去获取文本输入框内容,并根据输入内容更新文本显示框。
我们将开始使用Xcode来创建项目,启动Xcode(缺省情况下,Xcode位于 /Developer/Applications 里面),然后选择File & New & New Project,这样就可以创建一个新的工程。应该可以看到一个新的窗口,如下图所示:
选中 Window-Based Application 并点击 Next 按钮,输入Product Name(项目名):SayHello,在Company Identifier那,可以输入公司名唯一标识。
点击Next,选择项目存储位置,最后点击Create按钮。
完成上述步骤后,将看到如下的新项目窗口:
在进行下一步工作之前,可以先编译运行一下程序,这样就可以通过模拟器看到程序运行后的样子。在Xcode的菜单中选择 Product & Run 或者点击左上角工具栏上的 Run 按钮,iPhone模拟器应该会自动启动。当应用程序启动后,可以看到一个白色屏幕。
应用程序启动过程解析
通过Xcode的模板创建项目时,模板已经帮助设置好了应用程序基本程序环境,它会帮助创建一个应用程序对象,将应用程序和窗口连接起来,建立一个运行环境。整个启动过程从UIApplicationMain函数开始,如下图所示:
main.m文件中的main函数会调用UIApplicationMain函数:
int retVal =&UIApplicationMain(argc, argv,&nil,&nil);&
该函数将会创建一个UIApplicaion类的实例。同时它会搜索应用程序的Info.plist属性列表文件。 Info.plist文件是一部字典,它主要包含诸如应用程序名称、图标这样的信息,它也包含应用程序对象应该加载的nib 文件(虽然该文件的扩展名为&xib&,但是我们习惯称之为&nib 文件&)的名称。Nib文件主要有用户界面的信息。本项目的Info.plist文件具有下面的内容:
术语: 虽然Interface Builder文档的扩展名可能是&.xib& ,但历史上,其扩展名是&.nib&(&NextStep Interface Builder&的首字母缩写),因此人们就俗称其为&Nib文件&。&
这表明应用程序启动时将会加载MainWindow nib文件。在Xcode中可以单击MainWindow.xib进行查看(注意在Xcode4中已经不需要通过Interface Builder来打开nib文件,可以直接在Xcode对nib文件进行查看和编辑):
MainWindow Nib文档包含4个对象:
File's Owner,文件拥有者代理对象,在这里MainWindow的拥有者对象时UIApplication实例
First Responder,第一响应者代理对象,在本项目中,没有使用到
Say Hello App Delegate,SayHelloAppDelegate的实例,也就是应用程序的委托
Window,一个窗口对象。它默认是白色背景,程序启动时看到的就是它
应用程序对象在完成启动后,会向委托发送applicationDidFinishLaunching:消息,通知程序已经启动成功了,这样我们可以在收到这个消息后根据需要进行一些操作。下图是一个简化的iPhone应用程序生命周期图,简要展示了发生在应用程序启动到退出的过程。
这样,我们基本了解了如何创建一个项目,以及一个应用程序的启动过程,接下来,我们需要创建一个视图控制器(UIViewController)实例,用来实现项目功能。
添加视图控制器(UIViewController)
添加视图控制器文件
在iPhone应用程序中,视图控制器(UIViewController)起着核心作用。顾名思义,视图控制器负责管理控制视图。在iPhone上,它们也帮助进行导航和内存管理。
选中Xcode项目管理器里的项目(即SayHello项目,位于Groups and Files列表的顶部)或者选中SayHello文件夹&&新文件在添加时会被加入到当前选择的位置。 选中后,在Xcode菜单中选择 File & New & New File,也可以在选中的文件夹上面点右键,选择 New File。
在New File窗口中,请选择Cocoa Touch,然后选择UIViewController subclass。
点击 Next 按钮,在Options窗口,请勾选 &With XIB for user interface&复选框。选中 &With XIB for user interface&后,Xcode在创建视图控制器的同时,会为其创建一份nib文件,并将该文件添加到项目中。
点击Next按钮,在其后出现的保存文件窗口中,为文件起个名字,例如RootTimelineViewController,并选择文件存储的位置,如下所示:
点击 Save,文件会被添加到项目中。接下来,我们将创建控制器类的实例。
创建视图控制器实例
现在,我们有了视图控制器的类和nib文件,但要在应用程序代理中使用它,还必须创建类的实例,并且将实例存储在变量中,以便操作它。
在应用程序委托类的头文件(即SayHelloAppDelegate.h)中执行下述操作:
在一个类中访问另一个类,首先需要引用被访问类的头文件。所以我们先在应用程序委托头文件(SayHelloAppDelegate.h)的接口声明前面-即SayHelloAppDelegate声明前面引用视图控制器(RootViewController)的头文件:
#import "RootViewController.h"&
然后在头文件大括号之间添加下面的代码,这是为了向应用程序委托添加一个实例变量:
RootViewController&*viewC
在大括号之后 @end之前添加下面的属性声明:
@property&(nonatomic, retain)&RootViewController&*viewC
在头文件中添加完相应变量和属性申明后,需要在对应的实现文件中,合成属性的存取方法,在dealloc方法中释放视图控制器的实例。
在应用程序委托类的实现文件(即SayHelloAppDelegate.m)中执行下述操作:
在类的 @implementation代码块中通知编译器为视图控制器合成存取方法:
@synthesize viewC
在dealloc方法起始处释放视图控制器:
[viewController&release];
我们已经把视图控制器属性添加到应用程序的委托,现在需要实际创建一个视图控制器实例,并将其设置为属性的值。
在应用程序委托类实现文件(即SayHelloWorldAppDelegate.m文件)中的applicationDidFinishLaunching: 方法开头添加如下代码,这些代码用于创建一个RootViewController实例:
RootViewController&*controller = [[RootViewController&alloc]initWithNibName:@"RootViewController"&bundle:nil];
self.viewController =
[controller&release];
这段代码的作用如下:
创建RootViewController这个视图控制器的实例。使用alloc方法创建一个视图控制器,然后用initWithNibName:bundle:方法对其进行初始化。init方法先指定控制器应加载的nib文件,然后指定在哪个程序包中可找到该文件。程序包是文件系统某个位置的抽象,该位置存放了应用程序将会用到的代码和资源。
使用属性的存取方法,将创建好的视图控制器实例设置为viewController属性变量的值
根据内存管理规则释放视图控制器
视图控制器用来配置和管理在应用程序中看到的视图,每一个视图也对应有一个视图控制器来管理。窗体(window)有一个根视图控制器&&这个视图控制器负责配置当窗体显示时最先显示的视图。要让你的视图控制器的内容显示在窗体中,需要去设置窗体的根视图控制器为你的视图控制器。
所以我们的项目中,在上面创建视图控制器实例代码后面再添加一行代码,来设置窗体的根视图控制器为我们新添加的视图控制器:
self.window.rootViewController&=
最后一行来自于Xcode提供的模板自动生成的代码:
[self.window makeKeyAndVisible];
这行代码会让包含了视图控制器视图的Window窗口显示在屏幕上。
本章完整代码,SayHelloAppDelegate.h文件:
#import &UIKit/UIKit.h&
#import "RootViewController.h"
@interface&SayHelloAppDelegate : NSObject&&UIApplicationDelegate& {
RootViewController *viewC
@property&(nonatomic, retain) IBOutlet&UIWindow&*
@property&(nonatomic, retain)&RootViewController&*viewC
SayHelloAppDelegate.m文件:
#import "SayHelloAppDelegate.h"
@implementation SayHelloAppDelegate
@synthesize&window=_
@synthesize viewC
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
RootViewController&*controller = [[RootViewController&alloc]initWithNibName:@"RootViewController"&bundle:nil];
self.viewController =
[controller&release];
self.window.rootViewController =
[self.window makeKeyAndVisible];
return YES;
- (void)dealloc
[_window&release];
[viewController&release];
[super&dealloc];
在Xcode的菜单中选择 Product & Run 或者点击左上角工具栏上的 Run 按钮,iPhone模拟器应该会自动启动。当应用程序启动后,还是看到一个白色屏幕,不过第一次看到的白色屏幕,是应用程序代理中的Window,而这次看到的白色屏幕,是视图控制器RootViewController中的视图。
下一步,我们将开始对界面进行编辑。
编辑Nib文件
在iPhone开发中,一般都会用NIB文件来来负责界面显示,也就是MVC模型里面的视图对象,而NIB文件只包含用户界面元素,不包含任何源码,那么怎么让视图对象和视图控制器关联起来呢?这就需要用到两个非常重要的概念:插座变量(outlet)和文件拥有者代理对象(File's Owner)。
视图控制器的视图和Nib文件
视图控制器主要的职责就是配置和管理应用程序中所有的视图,一般来说,视图控制器的视图是放在一个Nib文件中,当然也可以不需要Nib文件,通过程序创建视图,典型的如UITableViewController这样的视图控制器,就可以不需要Nib文件。在创建视图控制器实例时,其中一个主要的构造函数&initWithNibName:bundle:&的第一个参数就是视图控制器对应的Nib文件的名字。视图控制器在其 loadView 方法中加载它的Nib文件。如果是使用&initWithNibName:bundle:&构造函数生成的实例,并且你想在视图加载完成后进行额外的设置,只要重写视图控制器的 viewDidLoad 方法就好了。
在Xcode中点击打开视图控制器的Nib文件(即RootViewController.xib文件),在Xcode中即可直接查看和编辑。文件包含三个对象,文件拥有者代理(File's Owner),第一响应者代理(First Responder)以及一个视图(View)。视图(View)是视图控制器的主视图,在主视图中还可以添加若干子视图。文件拥有者代理(File's Owner)代表Nib文件对应的视图控制器类。理解文件所有者代理的角色,以及如何建立文件所有者和Nib文件中界面元素之间的连接,是非常重要的。
小贴士: 在Xcode中编辑Nib文件时,可以通过点击右上角工具栏按钮&显示隐藏相应面板,方便对界面编辑和属性设置。&
文件拥有者(File's Owner)
在一个Nib文件中,文件拥有者对象是其中最重要的对象之一,因为正是通过它,来建立起应用程序代码和Nib界面文件中对象之间的连接,具体来说,它就是对应Nib文件的视图控制器对象。以本项目为例,RootViewController.xib这个Nib文件的文件拥有者对象就是RootViewController类的实例。
一般来说,在使用模板同时创建UIViewController文件和对应的Nib文件时,它默认会设置Nib文件对应的文件拥有者为创建的UIViewController类。如果要修改或者设置Nib文件对应的文件拥有者,可以使用 Identity Inspector 面板进行设置。
如上图所示, 本项目的RootViewController.xib文件对应的文件所有者,在Identity Inspector 面板中,Custom Class部分的Class项,可以看到对应的值是RootViewController,这表示文件拥有者就是RootViewController类的实例,就可以在Xcode中访问文件拥有者类里面标志为IBOutlet的属性和IBAction的方法,和Nib文件中的界面元素建立关联。
视图插座变量
在Xcode中,使用 Inspector 面板,或者在连接面板,可以查看、创建、删除对象之间的连接。要查看视图控制器的连接,可以通过以下步骤:
在Xcode的界面中,从左侧的文件组选中要查看的视图控制器的Xib文件
在视图编辑界面,点击选中 File's Owner
在 Inspector 面板,选中 Connection inspector,这里会显示文件所有者所有的插座连接
在视图编辑界面,按住Control键点击 File's Owner 或者在 File's Owner上点击右键,弹出一个黑色半透明的面板显示文件所有者的所有连接
在上面第三步,右侧面板显示的连接面板和右键点击File's Owner弹出的半透明连接面板,显示的信息和作用都是一样的,可以根据个人习惯灵活使用。到目前为止唯一的连接是视图控制器的 view 插座变量。一个插座变量就对应视图控制器类的一个属性(有时候也可以是一个实例变量),只不过这个属性和nib文件中的某个界面元素连接在一起。此处的view的连接,表明当nib文件 RootViewController.xib 被加载,并且UIView的实例解档之后,视图控制器的view实例变量会被设置为指向nib文件中的视图。
在项目开发中,尤其在对开发工具和语言不熟悉的时候,需要经常性的对新增的功能进行测试,以确保当前功能运行是正常的。比如我们新增了RootViewController这个自定义视图控制器,需要去测试一下它是不是已经成功添加。要测试视图控制器工作正常,简单的办法修改视图控制器的视图的背景色,例如修改为粉红色背景,然后重新运行,看看是不是界面变成了红色背景。
要设置视图控制器的视图的背景色,步骤如下:
在Xcode的界面中,从左侧的文件组选中视图控制器的Xib文件(RootViewController.xib)
在右侧的功能区域,选择属性面板(Attributes inspector)
在编辑区域,选择视图
在视图的属性面板,点击背景色(Background)对应的颜色下拉框,会弹出颜色选择面板
在颜色选择面板,选择一个合适的颜色,例如粉红色
保存nib文件
点击左上角工具栏的Run按钮,编译运行项目
正常情况下,编译应该不会出现任何错误,运行后会弹出模拟器,结果如下图所示:
确认没有问题后,再将应用的背景色还原。还原的话,将视图的背景色设置为白色就好了。
Xcode提供了一套对象库,可以直接添加到Nib文件中。其中一部分示界面元素,例如按钮和文本输入框;其他一部分是控制器对象,例如视图控制器。我们当前项目的nib文件已经包含了视图,现在只要添加按钮和文本输入框就好了。从对象库中将用户界面元素拖动到视图中,基本步骤如下:
在Xcode的界面中,从左侧的文件组选中视图控制器的Xib文件(RootViewController.xib)
在右侧的功能区域,显示对象库(object library)
添加一个按钮(UIButton),一个文本输入框(UITextField),两个文本标签(UILabel)到视图中。可以从对象库里面拖动并将它们放到视图
参考前面的原型设计,对界面元素的尺寸和布局进行调整
将右侧功能区域切换到属性面板(Attributes inspector)
选中文本输入框(Text Field),设置Placehold属性为&请输入姓名&
选中左上侧的文本标签(UILabel),设置Text属性为&姓名&
选中下面的文本标签(UILabel),设置Text属性为空,Alignment属性设置为居中对齐
选中按钮(UIButton),设置Title属性为&招呼&
设置好的界面如下所示:
如果我们想让用户在输入时有一些更好的体验,比如用户输入英文名时,默认会首字母大写;比如键盘会显示完成(Done)按键,点击后完成输入隐藏键盘。要支持这样的输入细节,通过设置文本框属性就可以完成:
在Capitalization下拉列表,选择Words,以支持首字母大写
在Return Key下拉列表,选择Done,以支持键盘上显示完成(Done)按键
保存文件后,编译运行程序,可以看到运行的界面效果和我们在Xcode中摆放的效果是一样的。点击按钮,按钮会高亮,在文本输入框中点击,会弹出输入键盘,键盘里可以看到完成(Done)按钮。但是还不能根据输入的内容去显示文字,还不能隐藏键盘,因为目前我们还仅仅完成了视图部分的工作,还需要让视图中的对象和视图控制器的对象之间建立连接,并添加相应的逻辑,才能实现。
实现视图控制器
实现视图控制器需要完成以下几件事:
定义插座变量和动作方法,和Nib文件的视图中的界面元素进行关联
实现点击按钮后的相关逻辑&&根据输入的名字显示相应的招呼语,判断输入的名字是不是为空是不是超长
用户点击键盘上的完成(Done)按键后,键盘会消失
从业务角度来看,我们需要和界面的几个元素建立关联:
文本输入框,获取它的输入文字
文本标签,让它显示特定文字
按钮,响应它的点击事件
在Xcode4之前,Interface Builder和Xcode是分开的,一般是先在Xcode中定义好插座变量和动作方法,然后再在InterfaceBuilder中去建立界面元素和视图控制器之间的连接,到Xcode4之后,Interface Builder和Xcode已经统一合并在了一起,所以这部分也有一些变化,Xcode4让这部分工作变的更加容易一些,可以直接从视图编辑界面拖动连接到代码文件。
在我们正在开发的SayHello项目中,现在我们需要添加一个动作方法到视图控制器,当界面上的按钮被点击时,它会发送一个sayHello:消息到视图控制器,所以接下来要为按钮创建一个sayHello:动作方法:
在Xcode中,选择视图控制器对应的Nib文件(RootViewController.xib)
显示Assistant editor
让Assistant显示视图控制器的头文件(RootViewController.h)
按住Control键,从Nib文件中的按钮拖动到头文件的方法声明代码区域
在弹出的面板中,将按钮和视图控制器之间的连接设置为动作(Action)
设置 Connection 为 Action
设置 Name 为 sayHello:
设置 Type 为 id
设置 Event 为 Touch Up Inside,也就是用户在点击按钮,然后释放后触发
设置 Arguments 为 Sender
点击Connect建立连接
通过上面的为按钮添加动作的操作,完成了两件事
添加了相应的代码到视图控制器的类中头文件中增加了如下代码:
- (IBAction)sayHello:(id)
并且实现文件中增加了相应的实现方法:
- (IBAction)sayHello:(id)sender {
IBAction 是一个特殊的关键字,它唯一的作用是告诉Interface Builder将某个方法当成目标/动作关联中的动作。它被定义为void。
建立了按钮到视图控制器之间的连接。建立连接的意义,等同于在按钮上调用 addTarget:action:forControlEvents: ,并且 target 是文件拥有者(File's Owner)也就是视图控制器,action 是 sayHello: 方法,对应的事件是 UIControlEventTouchUpInside。
接下来要建立文本输入框和文本标签之间的连接:
在Xcode中,选择视图控制器对应的Nib文件(RootViewController.xib)
显示Assistant editor
让Assistant显示视图控制器的头文件(RootViewController.h)
按住Control键,从Nib文件中的文本输入框拖动到头文件的方法声明代码区域
在弹出的面板中,将文本输入框和视图控制器之间的连接设置为插座(Outlet)
设置 Connection 为 Outlet
设置 Name 为 nameTextField
设置 Type 为 UITextField
点击Connect建立连接
通过上面的为文本输入框添加插座变量的操作,完成了两件事
添加了相应的代码到视图控制器的类中头文件中增加了如下代码:
@property&(nonatomic, retain) IBOutlet&UITextField *nameTextF
并且实现文件中增加了相应的实现方法:
在顶部增加了:
@synthesize&nameTextF
在 dealloc 方法中添加了
[nameTextField&release];
在 viewDidUnload 方法中添加了:
[self setNameTextField:nil];
IBOutlet是一个特殊的关键字,它唯一的作用是通知Interface Builder将某个实例变量或者属性当成插座变量。实际上,这个关键字被定义为空白,因此在编译的时候它没有任何作用。
建立了文本输入框到视图控制器之间的连接。建立连接的意义,等同于在视图控制器上调用 setNameTextFiled: 方法,将文本输入框作为参数传入。
按照上面创建文本输入框插座变量相同的方法,再建立用来显示问候语的文本标签的插座变量,并且将插座变量命名为 greetingLabel,类型为 UILabel。
实现逻辑代码
点击视图中的按钮,它会向视图控制器发送 sayHello: 消息,之后,视图控制器会取得文本输入框文字内容,根据内容来更新用来显示问候语的文本标签的内容。以下是RootViewController.m文件中 sayHello: 方法代码的实现:
- (IBAction)sayHello:(id)sender {
// 获取文本输入框内容,并存储到变量中
NSString *nameString =&nameTextField.
// 检查输入的名字是否为空,如果为空,弹出提示信息
if (nameString.length ==&0) {
UIAlertView *alertView = [[UIAlertView&alloc]initWithTitle:@"名字不能为空" message:@"请输入名字后,重新点击按钮。" delegate:nil cancelButtonTitle:@"确定"&otherButtonTitles:nil,&nil];
[alertView&show];
[alertView&release];
greetingLabel.text =&@"";
// 检查名字是不是超过16个字符,超过16个字符自动截断
if (nameString.length &&16) {
nameString = [nameString&substringToIndex:16];
// 根据输入的名字,生成问候语
NSString *greeting = [NSString&stringWithFormat:@"你好,%@!", nameString];
//&显示问候语
greetingLabel.text =
对于这个方法有几点补充说明:
UIAlertView是专门用来显示消息提示对话框
stringWithFormat:方法符串按照格式化字符串所指定的格式创建一个新字符串。%@表明此处应该使用一个字符串对象来代替。
编译并运行应用程序。在文本框中输入&Jim&,点击按键后,标签显示&你好, Jim!& 。但是选择文本字段进行输入,您会发现您没有办法表示已完成输入,也没有办法消除键盘。在iPhone应用程序中,当一个允许文本输入的元素变成第一响应者时,键盘就会自动显示出来,而当该元素不再处于第一响应者状态,键盘就会消失。我们不能直接向键盘发送消息,但是可以切换文本输入元素的第一响应者状态,利用该操作的附加效果来显示或消除键盘。在应用程序中,当用户点击文本字段时,该控件就会变成第一响应者,因此键盘就会显示出来。而当用户点击键盘中的Done按键时,希望键盘消失。
UITextFieldDelegate协议包含一个textFieldShouldReturn:方法,一旦用户点击Return按键,文本字段就会调用该方法(和按键的标题无关)。但将视图控制器设置成文本输入框(UITextField)的委托(Delegate),才可以实现该方法,在方法中向文本字段发送resignFirstResponder消息,这个消息的附加效果会让键盘消失。
通过以下步骤设置文本输入框的委托(delegate)连接:
在Xcode中,选择视图控制器对应的Nib文件(RootViewController.xib)
按住Control键,点击文本输入框
在弹出的半透明面板中,选中 delegate 后面的圆点,并拖动到 File's Owner
接下来,来实现将RootViewController作为文本输入框nameTextField的委托(delegate)
在视图控制器的头文件(RootViewController.h)中,在UIViewController后面添加&UITextFieldDelegate&:
@interface&RootViewController : UIViewController&UITextFieldDelegate& {
这个申明表示视图控制器RootViewController将支持UITextFieldDelegate协议
在视图控制器的实现文件(RootViewController.m),实现 textFieldShouldReturn: 方法:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (nameTextField == textField) {
[nameTextField resignFirstResponder];
return YES;
因为这个应用程序只有一个文本输入框,所以其实不需要包含nameTextField == textField检查。不过有些时候,对象可能会被设置成多个相同类型的对象的委托,这时候就需要来区分这些对象。
至此我们已经开发完成了整个应用程序。接下来将对它进行测试。
这个应用程序相对简单,我们设计几个测试场景:
输入正常的名字,例如&宝玉&,然后点击按钮,看看是不是会显示&你好,宝玉!&
不输入任何名字,点击按钮,看看是不是会有提示信息,要求输入名字。
分别输入16个、17个、20个字符的名字,看看名字是不是最多只能显示前16个字符
点击文本输入框,显示键盘,点击键盘上的Done按钮,看键盘是不是会隐藏
针对这个测试场景,逐一做一下功能的测试,看起来结果和我们预期的完全一样。
通过这样一个简单的项目,了解以下知识点:
iOS开发常用的一些设计模式
iPhone程序的启动过程
视图控制器和Nib文件如何建立连接
这些知识对于iPhone开发和iOS开发来说,都是会经常用到的知识。
阅读(...) 评论() &

我要回帖

更多关于 ajax之后重新加载css 的文章

 

随机推荐