逝水流年

This is a blog to record my life, my work, my feeling …

Uiscrollview被我忽略的一个属性

UIScrollView被我忽略的一个属性

最近在使用UIScrollView的时候,突然发现横屏滑动时没有按页滑动,停留的位置不满足要求。

刚开始觉得可能是scrollViewDidScroll里面计算页数不对,查了下发现不是这的问题。翻看头文件发现一个属性pagingEnabled,竟然跟page相关,难到是?试试设置为YES, 果然解决问题。

通过这个问题发现自己还是很多细节不够了解,一些属性和函数没有认真去研究过。之后需要主意下。

2015-06-05 Use NSTimer Attention

NSTimer 在使用中需要注意的几个问题:

  • NSTimer在UITableViewCell中使用是,需要将timer加到runLoop中。

    
      countDownTimer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(countDown:) userInfo:nil repeats:YES];
      NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
      [currentRunLoop addTimer:countDownTimer forMode:NSRunLoopCommonModes];
    
  • 同一个timer在重复使用之前必需invalidate, 否则会造成之前的timer无法停掉,两个timer同时存在。导致的现象就是timer同时更新两次。

2015-04-22 VVDocuemnter-Xcode Plugin Could Not Work Correctly

VVDocuemnter-Xcode plugin 是xcode上非常好用的一个插件,尤其适合做sdk接口的lazy programer。最为一个标准的懒人,必备之神器之一。但是当我安装完后却发现无法使用。怪哉,奇哉!

google 了一圈下来,没有任何收获。索性自己看看源码,再不济也可以调试下。(开源的好处在这时候体现的淋漓尽致.)

  • 运行自带Test, 没有问题。

  • 打印Log,发现生成comments正常。

  • 调试,终于发现了问题,下面三行代码,注意看comments Cmd+V, paste, 看到这里我突然想起来,我把paste的快捷键改成control+V了,再往下看keyCode支持command, alt, shift, control四种组合键,默认为command, 修改为我自定义的control后,重新安装,重启xcode,果然okay。

1
2
3
//Cmd+V, paste (If it is Dvorak layout, use '.', which is corresponding the key 'V' in a QWERTY layout)
NSInteger kKeyVCode = [[VVDocumenterSetting defaultSetting] useDvorakLayout] ? kVK_ANSI_Period : kVK_ANSI_V;
[kes sendKeyCode:kKeyVCode withModifierCommand:NO alt:NO shift:NO control:YES];

通过解决这个插件的问题,我知道了plugin的结构,了解了如何调试plugin,最终也解决了自己的问题。所获丰富,有时候问题是使自身进步最好的导火线!珍惜错误把!

2015-04-07 Summary Reports

截止4月3日,我来到新公司的第一个项目在一片混乱和加班声中落下了帷幕。这可能是我参加工作至今参加的最最混乱的一个项目。所以有必要整理下思路,将项目中的有缺点(主要是缺点:))总结纪录下,为自己也为他人提供一个参考。

我将问题分为几类,按照软件工程来分吧,反正每个阶段都有一些问题。

一、需求方面主要遇到的问的:

  • 需求不明确: 项目已经开始一周,需求还没敲定。

  • 需求变更频繁: 常常是到测试阶段了,需求还会变化。大boss竟然也会提需求,而且还是必须得实现。

  • 需求在QQ中讨论: 在qq群里讨论需求,导致得后果就是开发不知道需求,或者是很快就忘了。

  • 没有及时更新到文档上: 没有专门的需求文档和设计文档,有也是非常旧的版本,没有及时更新。

二、UI设计

  • UI设计原型图修改后不会及时更新。

  • 效果图不准确,也没有及时更新。

  • 标注图同上。

  • UI没有统一的标准,光颜色值就各自定义各自的。

三、代码管理

  • 代码没有标准。看工程中的代码,各式各样。

  • 没有code review。经常会导致代码覆盖或者是很简单的错误出现。

  • 没有CI,全靠手工打包。效率极低。

  • 模块划分不明确。

  • 业务逻辑和UI逻辑混在一起,无法维护和测试。

  • 无用代码或者无用的文件都混在一起,导致工程很混乱。相同定义出现多次。

  • 后台和前端周期安排不合理,经常前端做完后,后台接口还未完成。非常耽误进度。

四、测试

  • 没有Test cases.

  • Bug系统不支持Mac OS.

  • 测试没有规范及周期,完全依赖研发,测试过程比较混乱,版本追踪困难。

五、其他:

  • 项目周期制定拍脑门,不是根据具体需求细化后,根据每个feature的时间预估周期,而是指定死时间,在过程中不论需求如何变化,人员如何变化,周期永远不变化。也就是说一点风险控制的意识都没有。

  • 项目管理没有风险控制和变更控制。

  • 开发完全无法参与时间制定。

总之,问题很多,不局限我上面所列出的问题。有问题不可怕,可怕的是认识不到问题。从我来到项目结束,除了我及另外一个新来的同事提出过这样做不行,其他人都麻木了。每次我提出问题,总是会说习惯就好, 忍忍就过去了。这不是做事都态度!也不是我做事的准则。我来就是为了锻炼自己能力的,解决这些问题也是我的工作,所以我必须要改变这种状况才行。

很多问题肯定无法一下子解决,所以我将问题分两部分:1,是可以开发内部解决的问题。2,是需要其他部门一起改进的。

对于内部: 1. 我首先使用Jenkins搭建了自动build系统,增加版本号自动增加,将build和版本号对应起来。解决测试问题无法追踪版本及开发手动打包效率低问题。 2. 使用MVVM模式替换原来的MVC模式,分离business logic和UI logic。 3. 统一使用宏定义替换magic number。 4. 建议需求和UI统一管理一份(svn),避免需求和理解的混乱。

对于合作: 1. 积极提出改进建议:如UI规范统一。 2. 接口文档及时更新。 3. 测试统一依据效果图。 4. 对需求变化进行把控。(好像没有效果)

虽然当前项目没有太大的改进,但是在开发方面还是有很大的进步的。坚持好的习惯或者好的规范,也要有好的方法去推进。最近又将《软件作坊》这本书重新翻开,理论联系实践,理解的更加深刻。不论是对自己还是对公司都是又一些贡献。相当于双赢的局面。

2015-03-06 Solve Jenkins Build Xcode Project Could Not Found Provision Issue

The error is: Code Sign error: No matching provisioning profile found

How to solve:

1-Ensure the project is building successfully from Xcode to real target.

2-Copy all the development cretificates & credentials form your user folder to the system folder in KeyChain.

3-Copy all the Provisioning profiles existing in Users//Library/MobileDevice/Provisioning Profiles to /System/Library/MobileDevice/Provisioning Profiles.

If the directory is not exist, please create first.

参考: https://issues.jenkins-ci.org/browse/JENKINS-20916

2015-02-10 为什么要从一个舒适的工作环境中离开

我为什么要从一个舒适的工作环境中离开

今早乘坐7点06分点轻轨,我踏上了一天工作点旅程。中途在天津站倒车的时候,我看着屏幕上点时间7点23分,多么早啊。一个礼拜之前,这个时间我才刚刚起床,8点06分点轻轨让我轻松在9点一刻之前到达公司。为什么我要换个工作找罪受啊?我陷入深深点思考!我到底来这里要干什么?是仅仅为了赚更多点工资么?

经过一路点思考,我想我找到来答案。那就是要突破,要变的更强。在这个不太正规的公司,我到底能学到什么?我觉得应该是学以致用,把前几年积累的知识在这里用上,要在实践中出真知。只有实践才是检验我前段时间段成果。正好在这里可以发挥我的这些。一个不太正规的公司意味着更多的机会和挑战。

好吧,有了这个理由,我的心情就轻松很多,有了目标,下一步就是执行了,这恰恰是我的强项。加油吧!不是少年的少年!

工欲善其事,必先利其器

背景:最近一直在写些python脚本,同事review完发现一处地方不符合pep8规范,建议修改。

虽说是一处小小的改动,只要一分钟就可以搞定。但是我想下次会不会还犯这种错误?如何能一劳永逸解决这个问题?由于本人用vim作为python IDE,所以就去google了下是否有对python规范检查的插件,结果果然如我所料!万能的vim插件无所不能啊!因为早先已经用了syntastic插件检测语法,所以还是选择使用它来搭配pep8检测python规范。具体方法网上很多,这里不详细描述,感兴趣的可以自行google。

花了几个小时搞定好配置后,果然效果不错!为后面大量代码改动节约了不少时间,而且代码质量也提高不少!花费时间完全值得!这就是所谓的磨刀不误砍柴工。 有对vim感兴趣的同学,可以去我的github看看我的配置。欢迎交流。

字符串相关函数整理

string.h 中字符串相关函数

按功能分类:

  • 字符串连接:
    • strcat : char strcat(char destination, const char* source);
    • strncat : char strcat(char destination, const char* source, size_t num);

      cat 意思是catenate,连接的意思。 strnca 是strcat的安全版本,可以防止越界。 从定义上可以看出是将带const的字符串连接到不带const的字符串上。

  • 字符/字符串查找:
    • strchr : char strchr(const char str, int character); char strchr(char str, int character);

      查找字符character在str中第一次出现的位置,返回一个指针指向该字符到字符串结尾。 由于’\0’也是字符串的一部分,故该函数也可以查找结束符。 chr意思应该是character。

    • strrchr : char strchr(const char str, int character); char strchr(char str, int character);

      最后一次出现的位置。 ‘r’应该是right的意思,也就是从右开始搜索。

    • strpbrk : const char strpbrk(const char str1,const char str2); char strpbrk(char str1,const char str2);

      查找str2中任意字符在str1中第一次出现的位置,返回从整个位置到str1最后的字符串。不包含结束符。

    • strcspn : size_t strcspn(const char str1, const char str2);

      返回的是str1第一次出现str2中任意字符的位置。搜索包含null结束符,所以函数可以返回str1字符串的长度当没有任何匹配的时候。

    • strstr : const char strstr(const char str1, const char str2); char strstr(char str1, const char str2);

      匹配完整字符串

  • 字符串比较:
    • strcmp: int strcmp(const char str1, const char str2);
    • strncmp: int strcmp(const char str1, const char str2, size_t num);
    • strcoll: int strcoll(const char str1, const char str2);

      根据LC_COLIATE比较str1和str2。

  • 字符串拷贝:
    • strcpy : char strcpy(char destination, const char* source);
    • strncpy : char strcpy(char destination, const char* source, size_t num);

      拷贝source到destination中去。遇到’\0’停止copy。

  • 获取字符串长度:
    • strlen: size_t strlen(const char* str);
  • 拆分字符串:
    • strtok: char strtok(char str, const char* delimiters);

      tok的意思是token,该函数就是将str根据delimiter拆分。

Android NDK帮助文档的一个小错误

刚刚在调试如何不安装Cgywin的情况下,利用NDK编译cocos2d-x的SampleGame.却机缘巧合的情况下发现了android-ndk-r8ddocs/IMPORT-MODULE.html下的一个小bug。

在Eclipse中导入工程后,工程目录如下: image

  • 将工程转换为C++工程。这步不会的可以google下。

  • 设置ndk目录。 image

  • 设置NDK_MODULE_PATH环境变量。 iamge

在docs/IMPORT-MODULE.html中的介绍:

I.NDK_MODULE_PATH: The NDK_MODULE_PATH variable must contain a list of directories. Due to GNU Make limitations, NDK_MODULE_PATH must not contain any space. The NDK will complain if this is not the case. Use ‘:’ as the path separator. On Windows, use ‘/’ as the directory separator.

这里面说的Use ‘:’ as the path separator, 经过实践验证在windows平台路径应该是使用;分割.