├── .gitignore ├── AppointmentGuide.md ├── AppointmentGuideForAdmin.md ├── CodeStyle.md ├── CommonIssues.md ├── HelloFreshman.md ├── LICENSE.md ├── ProjectOrganize.md ├── README.md ├── TeamCola.md └── image ├── SetViewsLabelInStoryboard1.png ├── SetViewsLabelInStoryboard2.png ├── SetViewsLabelInStoryboardNegativeCase.png ├── make_ichat_auto_lunch_on_login.jpg ├── resource_file_organization.png ├── resource_file_organization_regroup.png └── teamcola_choice_a_category.png /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | .svn 4 | *.swp 5 | *.orig 6 | *.save 7 | ._* 8 | *.bak 9 | 10 | 11 | xcuserdata/ 12 | project.xcworkspace/ 13 | 14 | IOSInjectionProject/ 15 | .idea/ 16 | 17 | *.psd 18 | PSD/ 19 | -------------------------------------------------------------------------------- /AppointmentGuide.md: -------------------------------------------------------------------------------- 1 | < [Back](README.md) | [管理员版](AppointmentGuideForAdmin.md) 2 | 3 | 新人入职指南 4 | ==== 5 | 6 | 激活公司邮箱 7 | ---- 8 | 公司邮箱使用的是 gmail,登入 [https://mail.google.com](https://mail.google.com) 已激活。用户名是***你姓名的全拼***@chinamobo.com,密码是___你姓名的全拼___。 9 | 10 | 登入后你需要重设密码。后续你可能会受到一些邀请或帐号开通的邮件,请注意查收并按提示进行操作。 11 | 12 | 注:大陆访问 Google 服务多有不便,建议使用邮件客户端收取邮件,推荐使用 Mac OS X 自带的邮件应用。 13 | 14 | GitHub 帐号 15 | ---- 16 | 你需要把你的 GitHub 帐户告知负责人,如果没有你需要注册一个。 17 | 18 | 之后请 Watch 本仓库,以便有更新时收到通知。 19 | 20 | Google Talk 21 | ---- 22 | 公司内部指定IM(即时通讯软件,大白话就是聊天软件)是 gtalk,工作期间需要保持登陆。 23 | 24 | 强烈建议设置为开机时自动打开,设置方式可参考下图: 25 | 26 | ![登陆时打开信息应用](image/make_ichat_auto_lunch_on_login.jpg) 27 | 28 | 29 | 30 | 31 | 其他 32 | ---- 33 | 另见:[http://mobos3/w/index.php/员工手册](http://mobos3/w/index.php/员工手册) -------------------------------------------------------------------------------- /AppointmentGuideForAdmin.md: -------------------------------------------------------------------------------- 1 | < [Back](README.md) | [新人指南](AppointmentGuide.md) 2 | 3 | 新人入职流程 4 | ==== 5 | 6 | 准备邮箱 7 | ---- 8 | 1. 登入 [Google 域管理后台](https://www.google.com/a/cpanel/chinamobo.com/); 9 | 2. 创建相应新用户,使用全拼作为密码并强制下次登入修改; 10 | 3. 将用户加入相应 Groups。 11 | 12 | 加入到现有系统 13 | ---- 14 | 1. 创建新 GitLab 用户,并将其加入到必要的项目中。 15 | 2. [发送开发者邀请](https://developer.apple.com/membercenter/index.action#singleinvite) 16 | 3. 发送 TeamCola 邀请 -------------------------------------------------------------------------------- /CodeStyle.md: -------------------------------------------------------------------------------- 1 | < [Back](README.md) 2 | 3 | Chinamobo Objective-C 编码规范 4 | ====================== 5 | 6 | 目录 7 | ---- 8 | * [命名](#naming) 9 | * [基本原则](#naming-basic-principle) 10 | * [命名空间](#namespace) 11 | * [方法名](#naming-method) 12 | * [协议名](#naming-protocol) 13 | * [通知命名](#naming-notifications) 14 | * [临时变量命名](#naming-temporary-variable) 15 | * [常量命名](#naming-constant) 16 | * [大小写](#naming-match-case) 17 | * [缩写](#abbreviation) 18 | * [其他](#naming-others) 19 | * [代码格式化](#formatting) 20 | * [空格](#spaces) 21 | * [花括号](#braces) 22 | * [折行](#line-wrap) 23 | * [代码组织](#code-organization) 24 | * [类](#class) 25 | * [Property attributes](#property-attributes) 26 | * [注释](#comment) 27 | * [块注释](#block-comment) 28 | * [其他](#others) 29 | * [异常](#exception) 30 | * [参考](#reference) 31 | 32 | 命名 33 | ----- 34 | ### 基本原则 35 | 36 | * 仿照 Cocoa 风格来,使用长命名风格 37 | * 变量命名推荐的命名语素顺序是:最开头是命名空间简写,然后越重要、区别度越大的语素越要往前放。经典的结构是:作用范围+限定修饰+类型。例: 38 | 39 | ```C 40 | extern ushort APIDefaultPageSize; // 还行,能明白意思了 41 | extern ushort APIDefaultFetchPageSize; // 加上些限定更好一些 42 | extern ushort APIFetchPageSizeDefault; // 再好些,把重要的往前放 43 | 44 | YHToolbarComment // 不推荐 45 | YHCommentToolbar // OK,把类型(toolbar)置后 46 | ``` 47 | 48 | ### 命名空间 49 | * 类名、protocols、C 函数、常量、结构体和枚举应带有命名空间前缀; 50 | * 类方法不要带前缀,结构体字段也不要带前缀 51 | 52 | 53 | ### 方法名 54 | * 以 `alloc`、`copy`、`init`、`mutableCopy`、`new` 开头的方法要注意,它们会改变ARC的行为。[^1] 55 | * 以 `get`、`set` 开头的方法有特殊的意义,不要随意定义。 56 | 1. set 是属性默认的设置方法,如果函数不是为了设置类成员,则不要用 `set` 开头,可用 `setup` 替代。 57 | 2. get 和属性方法无关,但在 Cocoa 中,其标准行为是通过引用传值,而不是直接返回结果的。欲获取变量,直接以变量名为名,如:`userInfomation`,而不是 `getUserInfomation`。 58 | 59 | 例: 60 | 61 | ```Objective-C 62 | // OK 63 | - (NSString *)name; 64 | 65 | // 糟糕,应用上面的写法 66 | - (NSString *)getName; 67 | 68 | // OK,但极少使用 69 | - (void)getName:(NSString **)buffer range:(NSRange)inRange; 70 | 71 | 72 | // OK 73 | - (NSSize)cellSize; 74 | 75 | // 糟糕,应用上面的写法 76 | - (NSSize)calcCellSize; 77 | 78 | 79 | // 对 controller 做一般设置,OK 80 | - (void)setupController; 81 | 82 | // 列出具体设置的内容,更好 83 | - (void)setupControllerObservers; 84 | 85 | // 糟糕,set 专用于设置属性 86 | - (void)setController; 87 | ``` 88 | 89 | ```Objective-C 90 | // 来自官方文档 91 | insertObject:atIndex: // OK 92 | insert:at: // 不清晰,插入了什么?at 具体指哪里? 93 | removeObjectAtIndex: // OK 94 | removeObject: // OK 95 | remove: // 糟糕,什么被移除了? 96 | ``` 97 | 98 | ### 协议名 99 | 好的协议名应能立刻让人分辨出这不是一个类名,除了以常用的 delegate、dateSource 做结尾外,还可以使用 …ing 这种形式,如:`NSCoding`、`NSCopying`、`NSLocking`。 100 | 101 | 102 | ### 通知命名 103 | 基本命名格式是:`[与通知相关的类名] + [Did | Will] + [UniquePartOfName] + Notification`,例: 104 | 105 | ```Objective-C 106 | NSApplicationDidBecomeActiveNotification 107 | NSWindowDidMiniaturizeNotification 108 | NSTextViewDidChangeSelectionNotification 109 | NSColorPanelColorDidChangeNotification 110 | ``` 111 | 112 | ### 临时变量命名 113 | * 临时变量可以写得很短,如 i、k、vc 这样; 114 | * 临时变量可以使用匈牙利前缀,但数据类型不可以作为前缀: 115 | 116 | ```C 117 | // OK 118 | wCell, vcMaster, vToolbar 119 | 120 | // 糟糕,数据类型作为前缀 121 | bool_switchState, floatBoxHeight 122 | ``` 123 | 124 | 推荐的前缀: 125 | 126 | 前缀 | 含义 127 | -----|----- 128 | ix | 序号,起始为0 129 | in | 序号(自然数范围),起始为1 130 | if | 类型为浮点的“序号” 131 | x | 坐标 132 | y | 坐标 133 | w | 宽度 134 | h | 高度 135 | vc | 视图控制器 136 | v | 视图 137 | 138 | ### 常量命名 139 | 除以上规则约定外,其他常量约定了以下前缀: 140 | 141 | 前缀 | 含义 142 | -------|----- 143 | k | 宏常量 144 | CDEN | Core Data entity name 145 | UDk | User Default key 146 | APIURL | 接口地址 147 | 148 | 另见:[常量管理](#constant) 149 | 150 | ### 大小写 151 | * 类名采用大驼峰(`UpperCamelCase`) 152 | * 类成员、方法小驼峰(`lowerCamelCase`) 153 | * 局部变量大小写首选小驼峰,也可使用小写下划线的形式(`snake_case`) 154 | * C函数的命名用大驼峰 155 | 156 | ### 缩写 157 | 可以使用广泛使用的缩写,如 `URL`、`JSON`,并且缩写要大写。但像将`download`简写为`dl`这种是不可以的。 158 | 159 | 160 | ```Objective-C 161 | // OK 162 | ID, URL, JSON, WWW 163 | 164 | // 糟糕 165 | id, Url, json, www 166 | 167 | destinationSelection // OK 168 | destSel // 糟糕 169 | setBackgroundColor: // OK 170 | setBkgdColor: // 糟糕 171 | ``` 172 | 173 | 174 | ### 其他 175 | i,j专用于循环标号 176 | 177 | 为私有方法命名不要直接以“_”开头,而应以“命名空间_”开头。 178 | 179 | 代码格式化 180 | ----- 181 | ### 空格 182 | 类方法声明在方法类型与返回类型之间要有空格。 183 | 184 | ```Objective-C 185 | // 糟糕 186 | -(void)methodName:(NSString *)string; 187 | 188 | // OK 189 | - (void)methodName:(NSString *)string; 190 | ``` 191 | 192 | 条件判断的括号内侧不应有空格。 193 | 194 | ```C 195 | // 糟糕 196 | if ( a < b ) { 197 | // something 198 | } 199 | 200 | // OK 201 | if (a < b) { 202 | // something 203 | } 204 | ``` 205 | 206 | 关系运算符(如 `>=`、`!=`)和逻辑运算符(如 `&&`、`||`)两边要有空格。 207 | 208 | ```C 209 | // OK 210 | (someValue > 100)? YES : NO 211 | ``` 212 | 213 | 二元算数运算符两侧是否加空格不确定,根据情况自己定。一元运算符与操作数之前没有空格。 214 | 215 | 多个参数逗号后留一个空格(这也符合正常的西文语法)。 216 | 217 | 218 | ### 花括号 219 | 方法的花括号推荐另起一行。方法内部需要写在一行。 220 | 221 | ```Objective-C 222 | - (void)methodName:(NSString *)string { 223 | ↑空格 ↑空格,推荐花括号在一行 224 | if () { 225 | 空格↑ ↑空格,花括号不要另起一行 226 | } 227 | else { 228 | 要换行↑ ↑空格,花括号不要另起一行 229 | } 230 | } 231 | ``` 232 | 233 | **动机** 234 | > Xcode 默认的花括号位置是这样的:方法内部的各种补全都是在同一行的;方法定义的比较混乱,默认模版另起一行,但从 Interface Builder 中连线生成的方法在同一行的。 235 | > 236 | > 考虑到 Xcode 的默认行为,方法内部要另起一行,方法所在行不强制定死。另外,模版可以定制,而 IB 生成的代码不可定制,所以不另起一行的写法优先。 237 | > 238 | > 另起一行的写法在代码折叠后非常难看。 239 | > 240 | 241 | ### 折行 242 | 与多数其他规范不同,不建议手动折行。 243 | 244 | **动机** 245 | > 手动折行的效果严重宽度依赖于窗口宽度——窗口过宽浪费宝贵的屏幕空间,较窄时可能无法阅读。而且 Xcode 自动折行的效果还是不错的。 246 | 247 | 代码组织 248 | ---- 249 | * 函数长度(行数)不应超过2/3屏幕,禁止超过70行。 250 | : 例外:对于顺序执行的初始化函数,如果其中的过程没有提取为独立方法的必要,则不必限制长度。 251 | * 单个文件方法数不应超过30个 252 | * 不要按类别排序(如把IBAction放在一块),应按任务把相关的组合在一起 253 | * 禁止出现超过两层循环的代码,用函数或block替代。 254 | 255 | 尽早返回错误: 256 | 257 | ```Objective-C 258 | // 为了简化示例,没有错误处理,并使用了伪代码 259 | 260 | // 糟糕的例子 261 | - (Task *)creatTaskWithPath:(NSString *)path { 262 | Task *aTask; 263 | if ([path isURL]) { 264 | if ([fileManager isWritableFileAtPath:path]) { 265 | if (![taskManager hasTaskWithPath:path]) { 266 | aTask = [[Task alloc] initWithPath:path]; 267 | } 268 | else { 269 | return nil; 270 | } 271 | } 272 | else { 273 | return nil; 274 | } 275 | } 276 | else { 277 | return nil; 278 | } 279 | return aTask; 280 | } 281 | 282 | // 改写的例子 283 | - (Task *)creatTaskWithPath:(NSString *)path { 284 | if (![path isURL]) { 285 | return nil; 286 | } 287 | 288 | if (![fileManager isWritableFileAtPath:path]) { 289 | return nil; 290 | } 291 | 292 | if ([taskManager hasTaskWithPath:path]) { 293 | return nil; 294 | } 295 | 296 | Task *aTask = [[Task alloc] initWithPath:path]; 297 | return aTask; 298 | } 299 | ``` 300 | 301 | 302 | 303 | 类 304 | ---- 305 | 禁止在类的 interface 中定义任何 iVar 成员,只允许使用属性,但可以在特定情形中使用属性生成的 iVar。 306 | 307 | 尽量总是使用点操作符访问属性,而不是属性生成的 iVar 变量。以下情形除外: 308 | 309 | * 明确要避免修改产生 KVO 通知的; 310 | * 需重写属性 getter 或 setter 的; 311 | * 性能分析确定使用属性会导致性能不可接受的; 312 | * 多线程环境中,为防止互斥一次进行多个修改的; 313 | * init、dealloc 方法中。 314 | 315 | 动机 316 | > 如果使用 iVar,很多情况要特殊处理,容易出错。总是使用成员,规则简单,不易出问题。 317 | > 318 | > 直接访问 iVar 的 block 会 retain iVar 所属的对象,这点很容易被忽略 319 | > 320 | > 定义和使用 iVar 都会产生编译警告,只不过默认设置没启用这两个警告 321 | 322 | ### Property attributes 323 | 324 | 什么时候使用 copy? 325 | 326 | * block 属性要定义成 copy。 327 | * 当一个属性赋值后不期望改变时应当用 copy,最常见的类型如 NSString、NSURL。可变类型的成员,如 NSMutableArray、NSMutableDictionary 不能定成 copy 的。 328 | 329 | 相关 Demo 可在 https://github.com/BB9z/PropertyTest 获得。 330 | 331 | 常量 332 | ---- 333 | 除非调试用的、控制不同编译模式行为的常量可用宏外,其他常量不得用宏定义。 334 | 335 | 常量定义示例: 336 | 337 | ``` 338 | // 头文件 339 | extern ushort APIFetchPageSizeDefault; // 无const,可在外部修改 340 | 341 | // 实现文件 342 | ushort APIFetchPageSizeDefault = 10; 343 | ``` 344 | 345 | 注释 346 | ---- 347 | 尽量让代码可以自表述,而不是依赖注释。 348 | 349 | > 注释应该表达那些代码没有表达以及无法表达的东西。如果一段注释被用于解释一些本应该由这段代码自己表达的东西,我们就应该将这段注释看成一个改变代码结构或编码惯例直至代码可以自我表达的信号。我们重命名那些糟糕的方法和类名,而不是去修补。我们选择将长函数中的一些代码段抽取出来形成一些小函数,这些小函数的名字可以表述原代码段的意图,而不是对这些代码段进行注释。尽可能的通过代码进行表达。你通过代码所能表达的和你想要表达的所有事情之间的差额将为注释提供了一个合理的候选使用场合。对那些代码无法表达的东西进行注释,而不要仅简单地注释那些代码没有表达的东西。”[^2] 350 | 351 | ### 块注释 352 | 方法内部禁止使用块注释。除非要临时注释大段代码,一般情况总应使用行注释。 353 | 354 | **动机** 355 | > 因为块注释不能正确嵌套。 356 | 357 | 其他 358 | ------ 359 | 360 | ### 异常 361 | * 作为被调用模块的维护者,当被调用不当时(参数有问题、不和时宜),如何处理需要考虑(抛出异常还是返回错误状态); 362 | * 不要依赖 try catch,它不是代替你做检查、填补遗漏的工具。 363 | 364 | 365 | 参考 366 | ------ 367 | * [Coding Guidelines for Cocoa](http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html) 368 | * https://github.com/github/objective-c-conventions 369 | * https://github.com/jverkoey/iOS-Best-Practices 370 | * [你们是如何为 View Controller 的变量命名的呢? - V2EX](//www.v2ex.com/t/25732) 371 | * [代码大全(第2版) - 亚马逊](http://www.amazon.cn/dp/B0061XKRXA) 372 | 373 | 374 | [^1]: [再谈ARC - 苹果核](http://pingguohe.net/2012/06/22/talk_arc_again/) 375 | [^2]: [只对代码无法表达的东西写注释 - Tony Bai](http://bigwhite.blogbus.com/logs/125602412.html) 376 | -------------------------------------------------------------------------------- /CommonIssues.md: -------------------------------------------------------------------------------- 1 | < [Back](README.md) 2 | 3 | 常见问题强调 4 | ======== 5 | 6 | 201304 7 | ----- 8 | * 建议将 Storyboard 中的视图都用 segue 连接起来,即使实际页面间切换没用 segue。这样做的目的是增加 scene 间的关联性,让人明确知道界面间的关系。只把相关 scene 放在一起而不连线又是会比较模糊。 9 | 10 | 201303 11 | ----- 12 | * 视图必须正确设置 `autoresizingMask`。 13 | 14 | * 把一个 viewController 的 view 加入到另一个 viewController 的 view 时,必须用 `addChildViewController:` 方法把这两个 viewController 关联起来。 15 | 16 | * 给界面贴图一定要保证图片比例正确,避免拉伸失真。举例给按钮设置背景,图片的大小跟按钮的一致吗?不一致是不是要设置拉伸啊。@2x的图贴了吗? 17 | 18 | * 永远不要用 `CGRectMake(10, 10, 300, 200)` 这样的方式设置视图尺寸。如果你不得不强制设置视图位置的话,应该依靠现有视图和常量进行计算。比如: 19 | 20 | ```Objective-C 21 | CGFloat margin = 10.f; 22 | CGRect bounds = superView.bounds; 23 | CGFloat toolbarHeight = toolbar.frame.size.height; 24 | view.frame = CGRect(margin, margin, bounds.size.width - margin*2, bounds.size.height - margin*2 - toolbarHeight); 25 | ``` 26 | 27 | * 除非涉及 `UIWindow` 否则永远不要用 `UIScreen` 的尺寸。99%的情况都应参照父视图的尺寸。 28 | 29 | * 任务下发后有问题及时沟通,缺啥要啥,不清楚及时沟通,别等人来问你时才说。 30 | 31 | * 错误发生先看错误信息,错误是什么都没搞清就别问其他人了。 32 | 33 | * 如果一个任务你确定完不成了,赶快求助,别怕丢人。光憋在那里也提高不了,凭白浪费生命。没人笑话你(就算有那你也得给自己提高的机会吧)。 34 | 35 | 之前一些问题强调 36 | ---- 37 | * 常量定义:const与指针 38 | 39 | ``` 40 | // 错误写法,指向常量的指针,BGBookTypeID 可以指向其他字符串 41 | NSString const *BGBookTypeID = @"something"; 42 | 43 | // 与上面写法等价,但更明确 44 | const NSString *BGBookTypeID = @"something"; 45 | 46 | // 正确的写法,指向不可改变的指针 47 | NSString *const BGBookTypeID = @"something"; 48 | 49 | ``` 50 | 51 | * 在一个方法中要不要调用 super 方法是个问题,需要看文档。比如 `UIViewController` 的 `viewWillAppear:` 方法就有如下描述: 52 | 53 | > If you override this method, you must call super at some point in your implementation. 54 | -------------------------------------------------------------------------------- /HelloFreshman.md: -------------------------------------------------------------------------------- 1 | 2 | 优先学习方向 3 | ==== 4 | 5 | ARC、block、Storyboard、Core Data 这是最基本的,必须掌握,没什么好说的。 6 | 7 | AFNetworking 是我们在用的网络基础库,一上来可能觉着复杂,其实用起来很简单。如果你之前熟悉 ASIHttpRequest 的话,要比 ASI 好用。80% 的情况,请求一个接口就像下面一样简单: 8 | 9 | ``` 10 | [self getPath:@"http://example.com/api/do" parameters:@{ 11 | @"参数": 123 12 | } success:^(AFHTTPRequestOperation *operation, id responseObject) { 13 | // 处理返回数据 14 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 15 | // 处理错误 16 | }]; 17 | ``` 18 | 19 | 接口请求都是封装在 API 模块中完成的,具体可以参看已有项目。 20 | 21 | 之后,几个重要的主题是 GCD、KVO。 22 | 23 | 24 | 关于已有代码 25 | ---- 26 | 27 | 学习开发的一个重要途径就是阅读他人的代码,但是实际项目在进行中会有太多的限制,导致目前公司仓库里的代码很多不是学习的榜样。有两个重要原因: 28 | 29 | 1. 需求的变动。稍微大一点的项目基本都会有需求变动的情况,如果改变超出了预计,可能会产生不雅的修补,这种修补积聚而不能重构改善,就会导致项目改着改着就乱掉了。 30 | 2. 外包项目和做自己的产品是不一样的,外包项目不会给你时间精雕细琢,常常是“看上去”能用就OK了。 31 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2013 Chinamobo Co., Ltd. 2 | All Rights Reserved. 3 | -------------------------------------------------------------------------------- /ProjectOrganize.md: -------------------------------------------------------------------------------- 1 | < [Back](README.md) 2 | 3 | 项目组织规范 4 | ======== 5 | 6 | 欲达到的目的 7 | ---- 8 | 保证可维护性是最优先原则。其两个重要方面是:易于理解,易于修改。 9 | 10 | 代码可能只写一次,但阅读的次数很容易达到几十上百次,大型项目更是如此,几万都不止。保证项目易于理解,能大大节约团队时间,提高效率,更何况理解是进行开发的前提。 11 | 12 | 易于修改不必多解释,需求变化是正常的,需求不变是不正常的。 13 | 14 | 15 | 资源文件组织 16 | ---- 17 | 最新讨论决定,业务模块及其附属资源文件放在一起,而不是之前把图片专门放在 Resources 目录中。 18 | 19 | 下图是一个示例,右侧是实际文件摆放。通用的模块放在 General 下。 20 | 21 | ![资源文件组织示例](image/resource_file_organization.png) 22 | 23 | 随着某个 Group 中文件逐渐增多,必要时需要进一步分组以便维护。 24 | 25 | ![进一步分组示例](image/resource_file_organization_regroup.png) 26 | 27 | 由于 Xcode 中 Group(黄色文件夹)与实际文件目录中的结构没有强制的关联,这样会导致项目文件中的结构与文件系统中的结构不一致。调整的话需要手工移动文件,再重新加入到 Xcode 项目文件中,比较麻烦。 28 | 29 | 折中一下,规定保持 App 目录下第一层目录要一致,再下层不强制要求,能尽量尽量吧。以上图为例就是 Article、Button 等等 Group 下的文件都必须要在 General 目录下,至于 General 底下怎么组织不强制。 30 | 31 | 组织 Scene 中的视图树 32 | ---- 33 | “视图树”这种说法不太清楚,看下面两张图: 34 | 35 | ![Good example 2](image/SetViewsLabelInStoryboard2.png) 36 | ![Good example 1](image/SetViewsLabelInStoryboard1.png) 37 | 38 | 说的是这里面视图的组织。示例中已经给视图增加命名标注了,增加标注后一目了然。如果不去命名的话,可能会像这样: 39 | 40 | ![Bad example](image/SetViewsLabelInStoryboardNegativeCase.png) 41 | 42 | 如果在 Canvas 里视图很清晰,能立即分辨各个视图那很幸运。通常你不得不挨个看一下视图是跟哪个 IBOutlet 连起来的,如果变量的命名凑巧很糟糕可能还要看看代码具体是怎么写的。更糟糕点如果视图没任何连接,连判断这个元素到底有没有用到都不那么容易。 43 | 44 | 相对以上窘境,重命名操作真是举手之劳,选中视图然后按下回车就可以了。 45 | 46 | 视图顺序是从底到顶的,在不违反该原则的前提下,尽量按照实际布局以从上到下,从左到右的顺序组织视图。 47 | 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 如果你是新来的,请先阅读 [新人入职指南](AppointmentGuide.md)。 4 | 5 | 所有团队成员应 Watch 本仓库。 6 | 7 | 我们没有周报,但你需要每天记录工时,参见 [TeamCola 使用](TeamCola.md) 。 8 | 9 | 开发中的规范: 10 | 11 | * [编码规范](CodeStyle.md) 12 | * [项目文件组织](ProjectOrganize.md) 13 | * [常见问题强调](CommonIssues.md) 14 | 15 | 工具使用: 16 | 17 | * [Xcode 完全指南](https://github.com/BB9z/Xcode-Complete-Guide) 18 | * [Git工作流程](GitWorkflow.md) 19 | -------------------------------------------------------------------------------- /TeamCola.md: -------------------------------------------------------------------------------- 1 | < [Back](README.md) 2 | 3 | 4 | 工时记录 5 | ==== 6 | 7 | 经过投票决定,团队成员一致决定使用 TeamCola 记录工时,原有周报制度废止。请保证每天的记录。 8 | 9 | 10 | 基本原则 11 | ---- 12 | 13 | TeamCola 的时间单元是半小时,大家不必记录得很详细,工作如果比较碎的话四舍五入就好了,不必纠结。保证持续记录就好了。 14 | 15 | 16 | 关于分类 17 | ---- 18 | 19 | 记录的时候别忘了指定一个分类,为了便于区分,项目类以 `#` 开头,管理性质的工作以 `@` 开头,如下所示: 20 | 21 | ![选择一个分类](image/teamcola_choice_a_category.png) 22 | 23 | ### `已归档项目` 和 `其他项目` 24 | 25 | 为了减少列表长度,已经完成了的项目会被归档,你是不能添加日志到归档中的分类的,这时可以指定为 `已归档项目`。一个临时性的项目可能没有创建相应的分类,这时可以指定为 `其他项目`。 26 | 27 | 28 | 参考阅读 29 | ---- 30 | 31 | * [我们如何使用TeamCola - 彩程团队BLOG](http://blog.mycolorway.com/2011/05/29/how_we_use_teamcola_to_help_collaboration/) 32 | * [TeamCola背后的产品设计哲学 - 彩程团队BLOG](http://blog.mycolorway.com/2011/07/07/design-philosophies-of-teamcola/) 33 | -------------------------------------------------------------------------------- /image/SetViewsLabelInStoryboard1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/iOS-Team-Norms/ea63ba4e5e52ffdd6b58ea34f525c75b794dec0f/image/SetViewsLabelInStoryboard1.png -------------------------------------------------------------------------------- /image/SetViewsLabelInStoryboard2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/iOS-Team-Norms/ea63ba4e5e52ffdd6b58ea34f525c75b794dec0f/image/SetViewsLabelInStoryboard2.png -------------------------------------------------------------------------------- /image/SetViewsLabelInStoryboardNegativeCase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/iOS-Team-Norms/ea63ba4e5e52ffdd6b58ea34f525c75b794dec0f/image/SetViewsLabelInStoryboardNegativeCase.png -------------------------------------------------------------------------------- /image/make_ichat_auto_lunch_on_login.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/iOS-Team-Norms/ea63ba4e5e52ffdd6b58ea34f525c75b794dec0f/image/make_ichat_auto_lunch_on_login.jpg -------------------------------------------------------------------------------- /image/resource_file_organization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/iOS-Team-Norms/ea63ba4e5e52ffdd6b58ea34f525c75b794dec0f/image/resource_file_organization.png -------------------------------------------------------------------------------- /image/resource_file_organization_regroup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/iOS-Team-Norms/ea63ba4e5e52ffdd6b58ea34f525c75b794dec0f/image/resource_file_organization_regroup.png -------------------------------------------------------------------------------- /image/teamcola_choice_a_category.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limboy/iOS-Team-Norms/ea63ba4e5e52ffdd6b58ea34f525c75b794dec0f/image/teamcola_choice_a_category.png --------------------------------------------------------------------------------