71

写给前端看的 iOS 梳理 (上)

 6 years ago
source link: https://zhuanlan.zhihu.com/p/33693932?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

写给前端看的 iOS 梳理 (上)

阿里巴巴 前端工程师

去年双十一为了排查一些 Weex 性能问题开始接触 iOS 相关学习,恰逢今年 1 月份开始慢慢参与 iOS 业务开发,借此机会整理一下 iOS 开发中的一些基础知识,用于备忘,同时旨在通过系列文章让前端同学在日后碰到 iOS 的代码可以看懂,方便更好的理解端上的一些原理。

大纲

v2-af99f6f10a33a2a156dc9835042fc7d1_720w.jpg

《上》主要讲述在 iOS 的开发过程中碰到的文件格式和 Foundation 框架常用的类,《中》和《下》正在整理中,同时文中图片建议点击放大查看

文件格式

  • .h: 头文件也叫接口文件,提供对外访问的接口,包含类、方法和属性的声明,相当于类的用户手册
  • .m: 实现文件,用于实现 .h 中声明的方法,相当于类的工程细节
  • Podflie: 包管理文件,用于定义项目所需要使用的第三方库,类比 package.json
  • Podflie.lock: 依赖库锁文件,记录了需要被安装的 pod 的每个已安装的版本,便于团队协作包统一,类比 package-lock.json
  • .xib: 可视化文件,一个轻量级的用来描述局部界面的文件
  • .storyboard: 界面布局文件,承载对应 UIView 的视图控件
  • .pch: 预编译头文件,将一个工程中“不会常修改”代码预先编译好放到 pch 里面,用于存放公用宏、存放公用头文件、还可以管理日志输出
  • .plist: 属性列表文件,一种用来存储串行化后的对象的文件,通常用于储存用户设置或者一些捆绑的信息,也是数据持久化解决方案之一
  • .lproj: 多语言本地化文件夹,也即为每一种语言单独定义一份资源,有图片,文本,Storyboard,Xib 这些文件
  • .xcassets: 图像资源文件,用了存放图片资源
  • .xcodeproj: Xcode 工程文件,存储着 Xcode 工程的各项配置参数
  • .xcworkspace: Xcode 工程文件,使用 pod install 后生成的新文件,打开后可以同时看到项目文件和 pods 依赖包

Foundation 框架

首先介绍一下 Cocoa,Cocoa 是一套 OS X 和 iOS (Cocoa Touch) 中的框架和运行时支持,也即 API 应用程序接口,可类比于 VC 里面的 MFC。

Cocoa 其中最重要和 UIKit(OSX 为 AppKit)Foundation,两个框架在系统中的位置如下图, 同时可以看到常见的框架所在位置。

其中 UIKit 主要用于 iOS 界面构建的,后面详细介绍。

Foundation 框架给我们框架和 App 开发提供了基础层功能,用于访问基本的数据类型,集合和操作系统服务,包括如下:

  • 数据存储和持久化:NSArray、NSDictionary 以及 NSSet 为任何类的 OC 对象提供存储
  • 文本和字符串处理:NSCharacterSet 用于 NSString 和 NSScanner 类中字符串各种操作
  • 文件处理:NSFileManager 类 提供大量用于文件操作检查的方法
  • 日期和日期:NSDate、NSTimeZone 和 NSCalendar 类
  • URL 操作:提供一组类和协议来处理 URL 访问
  • 异常处理:NSException 类

Foundation 在 JS 里面可以假想成一个原生的公用 Util 库,But 没有...

OC 中@是做什么的 ?

  • 通常字符串前面会加一个@,用来将一个 C 语言的字符串转化为 OC 中的字符串对象 NSString
  • @ 符号 OC 中大部分的关键字都是以@开头的,比如 @interface,@implementation,@end @class

很多类之前的 NS 前缀是什么 ?

  • 在 OC 里不支持命名空间,所以只能通过加前缀这种土土的方法来避免命名冲突,所以常常会用 3 个大写字母(2 个的被苹果占了),可譬如开发者名称、公司名称或者方法名等来区分
  • NS 代表的是 NeXTSTEP,为 NeXT 公司开发的操作系统,NeXT 是 Jobs 在 1985 年离开苹果时候创建的公司名称,后来被收购回来后,很多成果被吸收到 OSX 基础中
  • 类似的还有,CF == Core Foundation;CG == CoreGraphics.frameworks;CA == CoreAnimation.frameworks;UI == UIKit 等表示

对象的可变性

OC 中的类可分为可变(mutable)类和不可变(immutable)类,这里不可变指的是字符串在内存中占用的存储空间固定,并且存储的内容不能发生变化,反之可变是指占用空间可不固定,内容可修改;这个和灵活的 JS 是很不一样的,但我更倾向于对数据类型区分可变和不可变,也便于后续的维护和扩展。

对于确定不会改变的类,它只具备应有的属性方法,可变类通过继承原有不变类,再增加可变方法属性即可实现可变。

可变类是不可变类的子类,同时所有可变类的实例对象可以作为不可变的实例对象来使用

NSString

在 OC 中使用 NSString 来表示字符串,可变 NSMutableString 继承不可变 NSString 类,好比一个字符串链表,可对其进行 增删改 操作。

NSArray

在 OC 中使用 NSArray 来表示数组类, 这里需要注意的是它不像 JS 的数组可以存入任何类型,在 NSArray 中只能够存入 OC 对象,同时也是不可变的,假如需要更改数组,需要使用它的子类 NSMutableArray。

通过arrayWithObjects方式创建的数组记得在最后一项加上nil,所以为了方便更推荐直接使用@[@"lnj", @"lmj", @"jjj"]方式创建,但是因为生成的是不可变数组,故在 NSMutableArray 中不要这么创建。

很多数组的操作方法和在 JS 中对比大致相同,不过 NSMutableArray 提供了比 JS 中一些更丰富的方法,包括交互两个元素位置这种需要自己写的方法,也即很多时候编写时候可以先查查文档看是否有这个方法, 很多时候可以从里面找到。

NSDictionary

前端同学第一次听到字典这个词可能会有些陌生,可以类比 JS 中的 Object, Java 中的 Map,字典中的数据也是通过键值对保存。

NSDictionary 属于不可变字典类,一般创建之后只能用于查询,不能对其进行修改操作,想修改需要使用 NSMutableDictionary 类。

NSDate

NSDate 可以用来表示时间, 用来进行一些常见的日期时间的处理,它的使用方式和 JS 的 Date 也是很相似的,[NSDate date] 返回的就是当前时间,但是在格式化日期时间上面 Foundation 处理比 js 要优雅很多,直接调用其内置方法即可。

通过和 NSDateFormatter 类配合使用可以格式化日期stringFromDate用于 NSDate 转 NSString,dateFromString用于 NSString 转 NSData:

//NSDate 转 NSString
NSDate *now = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *str = [formatter stringFromDate:now];
NSLog(@"%@", str);

// NSString 转 NSDate
NSString *str = @"2018-02-08 11:53:12";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *date = [formatter dateFromString:str];
NSLog(@"%@", date);

假如想在时间日期上面处理更复杂的内容,还可以借助 NSCalendar 类丰富我们的处理

NSDate *date = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
// 利用日历对象获取年月日时分秒
NSCalendarUnit type = NSCalendarUnitYear 
                    | NSCalendarUnitMonth 
                    | NSCalendarUnitDay 
                    | NSCalendarUnitHour 
                    | NSCalendarUnitMinute 
                    | NSCalendarUnitSecond;
// cmps 包括 year、month、day、hour、minute、second 属性
NSDateComponents *cmps = [calendar components:type fromDate:date];

比较日期,可以直接使用如下方法:

- (NSDateComponents *)components:(NSCalendarUnit)unitFlags 
      fromDate:(NSDate *)startingDate 
      toDate:(NSDate *)resultDate 
      options:(NSCalendarOptions)opts;

从上面看,OC 中很多方法都是很长很长的,并且将每一个参数代表的意思也表示出来了,不会出现错误对应的情况。

NSURL

写前端久了会慢慢觉得 URL 就是一条线上的链接 H5 地址,其实不然,URL(Uniform Resource Locator)中文意思是统一资源定位符,除了 http 协议之外,还有https/ftp/file协议用来访问一个资源

在 OC 中,操作 URL 时候应该用专用的 NSURL 类,而不建议把 URL 当做字符串来手工解析

随着后面的升级,原来在 OS 中很多文件输入输出的地方也开始使用 NSURL 了,也即慢慢地将网络当时 OS 中的一部分了。

NSNumber \ NSValue \ NSNULL 包裹类

Cocoa Fundation 框架的集合类(NSArray\NSDictionary\NSset)中只可以放入对象,前端同学可能开始时候会很不适应,假如想放入 int\float\double\bool 等基础类型,需要将其包裹成 OC 对象在进行放入,这里就需要使用 NSNumber 包裹类了,才能间接的将基础类型放入。

// 直接在前面加入@就可以创建一个 NSNumber 对象型
@10;
@10.5;
@YES;
@(num);

// NSNumber 类提取基础型
- (char)charValue;
- (int)intValue;
- (double)doubleValue;
- (BOOL)boolValue;

但是对于结构体、指针这种复杂的数据类型,NSNumber 也无法包裹,这里需要使用 NSValue 类,它是 NSNumber 的父类,可以将任意类型包装成对象。

// 结构体包裹,譬如 NSPoint、NSSize、NSRect
- (NSValue *)valueWithPoint:(NSPoint)point;
//从 NSValue 对象取出之前包装的结构体
- (NSPoint)pointValue;

前面的数组字典中是不能自己放入nil,因为在里面有结束的含义,但是有时候我们又确实需要一个特殊的对象来表示空值,这里就需要 NSNULL 了,可以通过类方法 +(NSNull *)null 来定义,同时可以通过if(obj==[NSNull null])来判断是否为 NSNull。

实际开发中极少使用NSNull,而且一般习惯也不会单独判断这个(默认大家都不用),所以用它也会很危险(大多数情况是用nil,nil可以接任何消息,但 NSNull 不行,二者特性的区别可能引起crash)。

通过以上文章,最多只能够让大家对 OC 编程有一些了解,谈不上深入,更多的是希望前端对于 H5/Weex 的深入了解和优化不要局限到最上面薄薄的一层,完全可以联系到底层的加载、渲染、图片库、网络库等等来进行优化。

从语言层面来说,OC 和 JS 还是挺有意思的,变量/方法命名的风格正好相反,苹果更加鼓励开发者程序命名尽量使用英文全称并且是尽可能详细,通过看到方法和变量就知道是做啥的,看写得好的 iOS 仿佛看散文一样,譬如 -(NSArray *) componentsSeparatedByString:(NSString )separator; 分割字符串,在 JS 里面直接通过 str.split() 就解决了,更多前端开发者习惯不长的命名,因为需要从网络下载,尽管压缩工具会做,但大家也习惯短命名来表示。

由于编译型语言缘故,写 OC 过程中很多错误可以在编译过程就发现,同时运行速度快,同时很多事情苹果都帮开发者做了,包括工程体系,这样其实写 iOS 可发挥的地方没有前端多;反之 JS 为解释性,性能更多依赖于引擎,加上为语言动态,写起来也爽,很多奇淫技巧可使用,加上 Node 的发展,让其可以做很多有趣事情。

各有优点,喜欢 Web 的快速和开放,也爱 iOS 的优雅体验和统一化

知乎阅读体验不是很好,假如你可翻墙,可见 GitHub Pages 写给前端看的 iOS 梳理

Recommend

  • 100

    【前言】 近一年多的时间,笔者在公司中担任过应届生导师、实习生导师、应届生项目导师等一系列导师角色。期间,笔者发现一些即将和准备成为前端攻城狮的同学其实并没有明确前端真正的核心和定位,也没有给自己制定一个学习和发展的方向。当初选择前端这个职业,也...

  • 71

    原文地址:A Front End Developer’s Guide to GraphQL 原文作者:PEGGY RAYZIS 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m… 译者:ellcyyang 校对者:Xekin-

  • 43

    张泉灵说,时代抛弃我们的时候连声再见都不会说,马云说对于新兴事物,绝大多数人是看不见、看不起、看不懂、来不及。自从学完 Coursera 上的 Crypto Currency 课程,搞懂区块链技术的本质后,对区块链的的所谓信仰变成了强有力的逻辑支撑,不管你看没

  • 49

  • 28

    THE SHORT STORY 只要两步就可以拥有以下页面。(猫是会眨眼的哦) 第一步:到你的博客后台管理,将博客皮肤设置为darkgreentrip 第二步: 分别粘贴以下代码到“页面定制CSS代码

  • 57

    相信越来越多的前端开发者已经迁移到VSCode阵营了,这里不对各大编辑器作比较。因为我怕杠不过各位。^_^ ··· VSCode快速,稳定而且能完美支持TS。 我对开箱即用的编辑器一直存在着好感,但是他们都或多或少的缺少点什么,但是广大的同胞打造的扩展(ext

  • 40

    为什么选择 Hapi 或许你已经使用过 Express, Koa2 等 Node.js 的 WEB 框架,在构建 WEB 应用程序时,你的工作仅仅是产出 RESTFUL API,或者通过 Node 调用其他网络接口。你或许感觉到是不是有一种更简单的方式来处理请

  • 47
    • 掘金 juejin.im 5 years ago
    • Cache

    写给初级前端的面试经验

    最近到了金三银四的跳槽季,很多人都会面临跳槽找工作,并且再过几个月又会到毕业季,越来越多的毕业生会面临这个问题。 同样,我们组因为业务需要(我们今年倒是还没有人员离职,感动╭(╯^╰)╮)需要进行社招,我最近看了不少简历,并且对一些小伙伴进行了电话沟通...

  • 37

    最爱折腾的就是前端工程师了,从 jQuery 折腾到 AngularJs,再折腾到 Vue、React。 最爱跨端的也是前端工程师,从 phonegap,折腾到 React Native,这不又折腾到了 Flutter。 低成本地为用户带来

  • 23

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK