猴子原创,欢迎转载。转载请注明: 转载自Cocos2D开发网--Cocos2Dev.com,谢谢!
原文地址: http://www.cocos2dev.com/?p=265
xib是个很好的东西,但是有时候在画cell的时候,里面的控件我会给它设置tag,用来在cellForRowAtIndexPath中获取每个cell的子控件,如果子控件有个UIButton,你给它设置targeta后,在响应的方法里没办法分是从哪一个cell的button触发的,因为所有的cell的那个UIbutton的tag是一样的。
既然不许改变tag,有没有其他办法知道它的父容器Cell的行数呢?知道行数了不会知道是哪一个cell的Button触发的。有了思路就不怕没办法。
我想到了利用Button的title。就是把不用的Button的状态,赋值title,title就是它所在cell的行数。然后在target中获取title,并转为int。得到的int就是行数了。
设置title:
NSString* cellStr1 = [NSString stringWithFormat:@"%d", indexPath.row];
[btn_attention setTitle:cellStr1 forState:UIControlEventTouchCancel];
获取title,并转为行数:
NSString* cellIndex = [sender titleForState:UIControlEventTouchCancel];
int tag =[cellIndex intValue];
这样就可以实现了。
不过一般来说最好是自定义cell,每个cell处理自己内部控件的响应。
如何使用,看自己的需求了,毕竟代码是死的,思路是活的。
关键词:android 4.0 nand 分区 userdata 大小 fdisk
平台信息:
内核:linux3.0
系统:android4.0.3
INAND:SDIN5C2-8G-L(SanDisk)
平台:S5PV310(samsung exynos 4210)
一、NAND分区大小:
我们的机器用的是8G的INAND,三星台一般把它分为四个区:
(1)、fat分区,作为sd卡用;
(2)、系统分区,相当为电脑c 盘,用来安装android系统;
(3)、userdata分区;
(4)、cache分区。
二、分区更改操作过程
1, 更改uboot中代码/common/cmd_mmc_fdisk.c
在这个文件中我们可以看到对四个分区大小的定义:
2,编译uboot 、烧录
#sudo fastboot flash bootloader u-boot.bin(三星平台的命令,不同平台也许不同)
重启,进入uboot命令行模式,一定要重启。
3,重新分区 fdisk -c 0
#fdisk –c 0 //重新把INAND分区
#fdisk –p 0 //查看INAND分区信息
如下所示,600MB为我们新分的空间。
4,把整个系统区重新格式化
系统重重分区后,原来烧录程序位置发生改变,系统分区(相当于电脑的c盘)也变化,所以要重新格式化。(下面的命令是三星平台下的,因平台而不同)
5、把整个系统重新烧录
6,打开机器,如下图所示,查看更改结果
三、fdisk 命令分析
1、命令定义
2、do_fdisk的实现函数
我们平时用的fdisk -c 0 格式化inand ,fdisk -p 0 查看分区信息,在这里可以看到对这两条命令的解析:
3、如果为fdisk -c 0进,进入 create_mmc_fdisk,我们再分析这个函数
4、我们看下格式化函数make_mmc_partition是怎么实现的吧。
这里面有两上参考比较重要:block_start 、block_offset;每个区块的开始和大小(偏移量),我们画个图来更好的表示这个吧。
在这里我们可以看到
这几宏的应用,block_start= calc_unit(CFG_PARTITION_START, sdInfo),计算分区大小
5、fidsk – p 0的实现函数也很简单
本文目的:把自己一阶段的东西进行总结,拿出来和大家分享,也希望从读者的评论那里得到启发。
本人水平:华东师范大学软件学院毕业,做过两个J2EE项目,一个J2ME项目,一个Android项目(基本就靠Java混饭吃)。
项目介绍:一款IM应用,类似于QQ,用户群是企业员工,和企业QQ是竞争对手。下载地址:http://apk.gfan.com/Product/App278699.html。
类似项目介绍:陌陌,QQ,微信等等,说白了就是手机即时聊天软件。个人认为,手机聊天软件中,光从用户体验来说,做的最好的是陌陌(也不妄称约炮神器,昨晚上我下载了陌陌,今天就钓到一个贵州少女)。
好了,言归正传,开始项目的点点滴滴。整个项目经历了前期需求分析,技术要难点定位,编码/测试,验收测试,上架(看了项目阶段是不是觉得有问题?他妈的确实有问题,后期吃了很多苦)。
前期需求分析:这个简单,就是在规定的项目时间内,计划完成多少功能。由于是给自己公司做产品,所以肯定要分一期,二期……,由于时间关系,我们第一期只完成最简单的单人聊天。然后根据其他已有的聊天软件,设计组给出了最初的设计稿(由于设计组人太少,只给出了最简单的原型设计,其他的,都是在PC组同事帮助下完成的功能设计)。
技术要难点定位:这里就简单的说了,从我开始做这个项目到现在,觉得有两块地方比较难。1.原始数据的拉取;2.通信协议的选择。下面展开分析。
原始数据的拉取:做一个聊天软件,大家可能觉得功能难点在聊天模块,其实不然,软件的初始化才是难点。要聊天,你总要有你的好友,好友的状态之类的数据哇。由于我们的软件是针对企业级的,数据量非常大,好友上限是20000,那么意思就是,你还没有聊天之前,可能要拉取20000人的基本资料……在这一块,开始参考了PC版的成熟算法,但是效果非常不理想,性能很棒的手机,在WIFI状态下,拉取20000人的账户,也要几分钟,这是用户不能接收的。后来采用的并发请求的方式,比较好的解决了这个问题。这里的并发指的是:逻辑层把要请求的数据包全部发送给网络层,网络层缓存起来,再不停的发送。(这种方式为什么比发送一个包,接收以后再发送下一个包好?不清楚的可以留言,我会回复)。现阶段,拉取5000人的账户,时间大概在30秒,当然还有优化的空间。做手机应用,应该有一个共识——弱化初始化。什么意思呢?就是登陆流程应该尽量简化,只拉取必要的数据,其他数据,可以在进入功能界面,用户开始使用功能以后再拉取。在本项目中,比如用户照片,用户状态等,都可以在“非繁忙”时段拉取,这样,初始化速度会快很多,用户体验会好很多。
补充一些额外的点:
1.通信数据格式:在这种数据密集型的项目中,采用XML,json之类的格式,绝对是找死,你可以很轻松的做出来,但是在正常的网络环境下,你的通信速度,绝对会比同类产品慢一拍,因为你的数据格式决定了你的数据大小,数据大小决定了通信时长。比较通用的做法就是自己拼凑byte数组,规定每个byte要表达的意义,然后一次通信规定一条协议,这可以最大程度的减少通信的数据。
2.数据库:由于聊天软件,多用户是必然的,而针对于我们这样的大数据项目,数据库的设计也是一个难点。数据库的设计是我单独完成的,我采用的是一个用户对应一个数据库,这样数据库的查询数据可以得到一定的保证。同时,为了数据响应速度,在适当的尺度,可以考虑冗余数据来减少多表查询,这对速度有很大的帮助。最后,在大批量的插入和读取时,有三点可以帮助我们提升速度:A.使用原生sql语句,而不是android封装的API,封装,代表着优雅,但是也代表着效率低下,在小数据量的时候,我肯定采用android的API,傻逼才用原生语句。但是一旦数据量大了,你就需要掂量掂量。 B.使用sql预编译,这样可以减少sql语句编译次数,也可以较大程度的提升性能。C. 使用事务,把多条sql语句放在一个事务中完成,既可以保证数据的完整性,也可以大大的提升性能。在5000条数据的插入测试中,使用上面每一点,基本上都可以提升一倍的速度。简而言之,比如你做一个大批量的插入,开始需要1分钟,但是采用了这三种方式,你最终的时间,只需要几秒钟。(需要成熟实例代码的可以留言)
编码/测试:大家也看到了,技术难点分析以后,就开始编码了,他妈逼的,连一个系统架构设计,或者编码规范制定都没有。这样的导致的结果就是,到了项目后期,由于开始没有做任何的项目规范,每个人的实现方式不同,整个代码的风格非常不一致,每个人负责的那一块,出了问题,只能由当事人修改…… 而且由于开始没有良好的系统架构,整个项目模块之间耦合性非常的高,修改一个地方,极可能引起其他问题。程序员非常被动。对不起,我已经无力吐槽了,笑,懂?
测试:以前我很讨厌测试人员,总觉得他们在找麻烦,但是如果你真的想做好一个应用,一个优秀的测试是多么的重要,尊重测试人员吧,他们重复无数次无聊的操作,仅仅是为了找到你犯的错。当然,有些测试也很讨厌,特别是验收测试中(就是快上线了),一个屁大的问题,非要闹的大家都知道,整的开发人员很没有面子,其实在验收测试中,小bug是可以下期再修改的,这个大家都可以理解。
上架:在上架之前,简单说一下打包的问题,打包的时候,要自己生成一个key,那么,这个key的有效期最好是长一点(怎么的也要50年吧),而且这个key一定要保存好,你的应用,在以后的任何一次打包中,都应该使用这个key,如果你不这样做,也可以,等着老板骂娘吧。
下面谈一下项目中遇到的一些问题:
1.软件进不去:由于项目数据量比较大,在性能差一点的手机,拉取数据过程中,总是stack溢出,导致登陆失败,然后软件退出。后来发现是使用了递归方法,当然,为什么使用递归就会导致stack溢出也没有去查(有些人就是喜欢把问题解决了就算了,真正的原因不关心),直接使用了for循环替代递归。当然,从大学学习算法的时候,我就没有搞懂递归,始终觉得,可以设计递归算法的人,很厉害……
2.CPU消耗达到90%:QQ的CPU消耗基本在1%以下,而我们的应用居然不小心就达到90%,你让我情何以堪啊…… 后来采用工具分析,也没有分析出什么玩意(可能是我笨),但是笨鸟先飞,老子不知道问题在哪里,那我就一段代码一段代码的注释,直到找到有问题的类,方法,代码段。后来才发现,有一个消息循环没有退出,只要运行到那里以后,就会一直给UI线程的消息队列发送消息,这样导致CPU消耗非常高。CPU消耗高了以后,机器就会发热,热到烫手,都他妈的可以煮鸡蛋了…… 而且我把手机连上电脑,边充电边调试,一会儿就会报电量不足,要停一会儿,才可以继续……
3.用户界面卡死:引起原因,在多线程同步的时候,大量使用全局对象锁,导致等待,卡死。在这里给各位屌丝普及一下Java锁的种类(在d8,估计清楚这点的不超过三个),Java锁分为两种,一种是类锁(synchronized加在方法上,而且方法有static关键字),一种是对象锁(synchronized加在方法上,但是这个方法不是静态方法,或者直接是synchronized代码块)。在使用synchronized的时候,范围要尽量小,而且采用的锁对象波及的范围也要小(听不懂的可以留言,就这一点展开说都至少要写一篇文章)。
4.软件不能正常退出:可悲的是,现在都还没有找到具体原因,采用了网上说的多种方案,都他妈的退不出去,具体的bug是activity被杀掉的时候,又莫名其妙的启动了。后来的解决办法是在每个activity生成的时候,给它注册一个广播,然后要杀死所有activity的时候,只需要发送一个广播,其他的就不用管了。
5.沟通:这里讲两个小例子:一个是我同学,他大学基本上没有敲过代码,第一家公司和我一样,也觉得他敲代码的能力不强,但是领导很认可他,后来我才发现,这个人很会交流,他不懂的话,他就把问题抛出来,让大家一起解决。整个团队效率很高,但是有很多程序员不是这样…… 第二个例子:我们项目组的人就特别不喜欢交流,严重到他在认真敲代码的时候,你去问他东西,他都很不乐意。当然,他有问题,也不会抛出来,都自己搞…… 记得我一个类中有一个方法,我是自己用的,使用的是private关键字,结果,后来程序报错,就报在这个方法,我才发现,这个方法被别人改为public了,而且到处在调用,真的,我无力吐槽……
6.未解决问题:长时间运行于这后台,程序被Android系统杀死。个我实在是没有找到合适的解决办法,参考了QQ的表象(从软件行为判断,具体的实现我也不清楚),在系统杀死程序的时候,通知栏图标并不会消失,QQ的实现方式估计是:在程序被杀死以后,如果有新的消息,则服务器push到手机,一旦手机接收到消息,则发出提醒(通知栏,声音,震动),用户点击通知栏时,则重新初始化程序。这样的结局就是:用户一致可以收到消息,也就是达到了一个目的:程序一直在运行的假象。如果有这方面经验的朋友请不吝赐教……