我比较推崇通过尽量利用编程中的元数据配合一些规约来进行功能实现.这里的元数据包括字段名,字段类型,方法名等等等等,任何你在编程的时候输入的字符实际上都可以作为元数据的一种,所以这篇文章的中心思想就是让你输入的每个字符都有含义,并且利用这些含义 .那么通过利用每个字符的含义可以大大节省代码量从而提高编码效率 .下面就是通过一些例子和技巧来展示这个思想.

Read More

有感于我厂某iOS项目的开发管理混乱,所以这里说一下我这边对Xcode工程的一些管理经验

  • 如果开发人数很多,且负责不同的部分和组件的话,可以用子Project的方式或者Workspace+多个Project的方式来分割功能和组件

由于project.pbxproj这个文件很容易发生冲突(比如新增文件,删除文件,改变Build Setting等都会改变这个文件),且很难合并冲突,那么采用多Project的方式可以降低project.pbxproj冲突的机会,而一些公用的代码或组件也可以放在一个Project中,然后其他Project来依赖这个公用的Project就可以搞定了

  • 使用CocoaPods管理第三方的组件和类库

至于什么是CocoaPods,可以看这篇文章 http://blog.zephyrleaves.net/?p=712

使用CocoaPods可以极大减少对依赖包的管理成本,现在AppCode 2.5已经开始原生支持CocoaPods了,Xcode上也有对CocosPods的支持插件 https://github.com/ricobeck/KFCocoaPodsPlugin

  • 对于需要打出不同渠道或不同测试环境的包,可以通过Build Configuration来进行区分

在Xcode项目->Project->Info->Configurations下面可以点+号添加自定义的Build Configuration(默认只有Release和Debug),然后针对不同的渠道和环境配置不同的Build Setting,当然一些渠道的配置也可以走XCCONFIG的方式进行配置,不过我还是建议走Build Configuration,因为这样很容易配置Scheme

  • 用Scheme来配置打包对应的Build Configuration 以及 执行 对应的 Build Configuration

由于不同渠道和环境通过Build Configuration来进行区分配置,那么执行和打包的入口就需要由Scheme来进行管理,特别是在使用CocoaPods管理的情况下,整个工程是用workspace来进行管理的 ,这个时候使用xcodebuild的时候就必须指定Scheme了

在Manage Schemes下面,可以创建多个Scheme(默认应该有一个对应Target的一个Scheme),在Edit Scheme里面可以设置不同Action(Run/Test/Profile/Analyze/Archive)对应的Build Configuration是啥,我这边是一个Build Configuration对于一个Scheme,这样很方便

由于Scheme都是放在个人的userdata下面的,所以在Manage Schemes下面对Scheme选中Shared,那么这些Scheme就可以被共享给团队的其他成员看到并使用了

  • 使用xcodebuild命令打包

由于一般情况下可能需要对多个渠道打出多个app包,如果对每个渠道都先clean在archive需要多个操作,实际上如上有配置对应渠道的Scheme后,可以用xcodebuild命令一次打出过个包来,比如:

xcodebuild -workspace XXX.xcworkspace -scheme XXX clean archive 
xcodebuild -workspace XXX.xcworkspace -scheme XXX_91 clean archive

写这样一个shell,就可以一次打出2个archive了

OK,上面这些都是我管理Xcode工程的一些经验,如果大家有更好的一些实践的话,都可以来告诉我哦

CocoaPods是Xcode上的一个依赖管理工具

CocoaPods有点像Java领域的Maven.当然它并不是作为构建工具存在的,构建还是由Xcode来负责,CocoaPods主要负责了各个类库的依赖管理,而且强大的是它还有自己的资源库..而且对比Maven它的依赖管理更加灵活,可以直接依赖本地的库或者自定义依赖一个git上的库.这点和Gradle很像

Read More

线上的CrashLog利用UserTrack的搜集的话一般都无法识别,比如

3   XXX                          0x00126adf XXX + 1006303
4   XXX                          0x0005ff49 XXX + 192329
5   Foundation                          0x33a864a1 <redacted> + 460
6   CoreFoundation                      0x331438f7 <redacted> + 14
7   CoreFoundation                      0x331431f3 <redacted> + 362

那么怎么去识别这种CrashLog呢?

Mac提供了一个dwarfdump的小工具来解析这种CrashLog,需要dSYM的配合

利用dwarfdump --lookup=ADDRESS DSYMFILE 的方式查找crash出错的地址在DSYM文件中的代码段

我这里提供一个Python的小工具,直接输入address offset(就是上面的堆栈里+号后面的那个数字),生成一个可读的堆栈

#!/usr/bin/python
# wentong@taobao.com
# 13-5-3
#
import optparse
import os

DSYM = ""

def map_hex(x):
    return """dwarfdump --lookup=%s %s|grep -E "start_addr:|Line table file:";echo -------------------; """ % (
        hex(0x00001000 + int(x)), DSYM)

def add(x, y):
    return x + y

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option("-l", "--list", dest="list",
                      help="addresses of the backtrace")

    parser.add_option("-d", "--dsym", dest="dsym",
                      help="the file of dSYM")

    (options, args) = parser.parse_args()
    if options.list is not None and options.dsym is not None:
        DSYM = options.dsym
        alist = map(map_hex, options.list.split(','))
        command = reduce(add, alist)
        # print command
        os.system(command)
        pass
    else:
        parser.print_help()

使用方法就是

iOSCrashAnalyza.py -l1067213,1006303,192329,11307 -d/Users/zephyrleaves/crash/XXX.app.dSYM

其中l后面就是跟 3 XXX 0x00126adf XXX + 1006303 这行中的1006303 这个数字

直接输出

Line table file: 'XXXX.m' line 74, column 56 with start address 0x00000000001058bc
    start_addr: 0x0010581c YYYY
-------------------
Line table file: 'AAAA.m' line 182, column 5 with start address 0x00000000000f6aae
    start_addr: 0x000f659c -[AAAA BBBB:]
-------------------
Line table file: 'CCCC.m' line 2028, column 2 with start address 0x000000000002ff48
    start_addr: 0x0002fef8 -[CCCC DDDD]
-------------------
Line table file: 'main.m' line 16, column 51 with start address 0x0000000000003bf6
    start_addr: 0x00003be4 main
-------------------

这样的可读的堆栈了

  • 更新了连接分配算法,能使连接平均的分配到io线程上,让io线程发挥最大效果
  • 支持了Between操作
  • 优化了 show processlists的输出 能看到当前执行线程 正在执行那个ip的客户端发过来的 多少id的请求
  • 支持 TC Malloc
  • 修复了一些bug

大家可以在https://github.com/alibaba/TDH_Socket 下载试用

最近更新的功能还在develop分支上哦,别看错了

MBMvc 就是Message Based MVC的简称

是iOS上的一个基于消息的MVC框架

使M/V/C之间的交互全部通过消息机制来完成,不会相互引用,这样就不会因为有引用导致的各自生命周期的混乱

因为没有引用那么也会消灭由于循环引用导致的内存泄露野指针导致的Crash

通过消息话也能使UI逻辑和业务逻辑异构,直接在不同的线程运行不会相互干扰使UI更流畅

而V/C 之间 也提供了数据Bind的方式达到完全解耦,相互的交互通过数据来驱动,不会有直接引用,从而解决有回调而导致的Crash或内存无法被及时释放的问题

而C/M 之间 也可以通过proxy的方式让 方法执行直接被消息化. 这样消息是可以被拦截并重放的,就可以很简单的作AOP(已经支持拦截器)

MBMvc的整体架构:

enter image description here

现在MBMvc开源了 在 https://github.com/alibaba/MBMvc

大家可以来玩玩