/->UIViewController | ViewController在iOS只是一个非常重要的概念,其在一个App中所扮演的角色, | (1) View Management:管理View (2) Data Marshalling:管理数据 | (3) User Interactions:响应用户交互 (4) Resource Management:管理资源 | (5) Adaptivity:适配不同的屏幕尺寸空间的变化 | ★ 生命周期【一片枫叶点击 另外一篇点击】 | + (void)initialize +(void)load 的调用时机,区别【点击】 | ViewDidLoad调用时机:当view被首次使用的时候,某些情况可提升性能 |-> UIView | frame 和bound 的区别【点击】 | frame 是相对父试图坐标的值; bound是本身坐标系统的值 | layoutSubviews【点击】 需要将[super layoutSubviews];放到最后,不然iOS7有可能会有这个崩溃 | ★ "Auto Layout still required after executing -layoutSubviews” iOS7上崩溃sdk缺陷 【点击】 | 每一个视图有唯一的父视图【点击】。addsubview操作把它从上一个父试图中移除 | 善于使用hidden 使用animateWithDuration简单地控制页面切换效果 | 使用animateWithDuration简单地控制页面切换效果【点击】 | ★简单动画 animateWithDuration【点击】 |->CALayer | CALayer是个简单的类,它是用来在屏幕上显示内容展示的矩形区域.【容芳志出品点击】 | 直接从NSObject继承,少了UIResponder类,固CALayer悲催的不能响应任何用户事件【点击】 |-> UIWindow | 每一个IOS程序都有一个UIWindow | UIWindow有三个层级,分别是Normal,StatusBar,Alert【点击】 | keyWindow是指定的用来接收键盘以及非触摸类的消息, | 而且程序中每一个时刻只能有一个window是keyWindow。 |-> UIImage | 加载图片几种方式【点击】 | [UIImage imageNamed:@“xxx”] 系统缓存到cache中 | [UIImage imageWithContentsOfFile:path] 不缓存 | [UIImage imageWithData:data] 不缓存 | ★ 拉伸图片,四角保持不变 resizableImageWithCapInsets: | ★ 加载gif图片【点击】 |-> UILabel【点击】 | 没有上下居中对齐,可以使用TTTAttributedLabel / /-> UIKit | \ | |-> UIButton | | 设置颜色,文字一定要指定button状态 | | 善于使用contentEdgeInsets,可以设置文本边距【点击】 | | 设置圆角可layer.cornerRadius | |-> UITextfield | | 隐藏键盘,[textfield resignFirstResponder] | | ★ 任意页面隐藏键盘【点击】 | |-> UITableView | | 复用,注意重写 - (void)prepareForReuse | | dequeueReusableCellWithIdentifier 从重用池中获取,可能是nil | | dequeueReusableCellWithReuseIdentifier 同上,但是不会是nil | | 插入,删除,移动section或item的顺序,需遵循下面两个步骤【点击】 | | 1. 更新dataSource的数据 | | 2. 调用相应的collection view方法删除或者插入section或item | | ★非常严格的条件:,在更新collection view之前,先更新datasource, | | 因为collection view总是假设你已经准备好打他source了 否则collection view收到错误的item,并造成crash | | 右侧音序条【点击】 | | UITableView上拉、下拉原理【点击】 | | AsyncDisplayKit 流畅的解决方法【点击】 | | ★当tableView正在滚动的时候,如果reloadData,偶尔发生App crash的情况【点击】 | |-> UIDevice | | 设备名 [UIDevice currentDevice].name, | | 系统版本号 [[UIDevice currentDevice].systemVersion doubleValue]; 【点击】 | | 屏幕旋转方向 [[UIDevice currentDevice] orientation] | | 区分iPad还是iPhone [UIDevice currentDevice].userInterfaceIdiom); | |-> UIScreen | | 如何正确的绘制1像素的线【点击】 | | 保证边距不变,内容等比例拉伸【点击】 | \->自动布局 | Masonry | | /-> NSObject 既是对象也是协议,可以将对象自动置nil 比如 int = 0 bool = NO | | 几乎所有类的基类或者协议【点击】 | | isKindOfClass:和isMemberOfClass:,通过这两种方法可以确定一个类的从属关系\ | | 后者测试一个接收器是否是一个指定类的实例;而后者可以测试类的从属关系。 | | respondsToSelector: 方法测试一个接收器是否通过selector实现(implements)了一个标志符话的方法 | | description方法,允许一个对象返回一个字符串来描述它的内容;这个常用于调试debug | | encodeWithCoder: 和 initWithCoder:方法,NSCoding协议中仅有的组成成员\ | | 第一个允许对象编译它的实例变量,第二个允许一个对象初始化它自身的解码实例变量。 | | conformsToProtocol:方法,测试接收器(对象或者类)符合一个给定的协议(protocol) | | ★__weak如何实现对象值自动设置为nil的【点击】 | |-> NSString & NSMutableString | | NSString作为属性时候,用copy还是strong修饰? | | strong是单纯的增加对象的引用计数,而copy操作是执行了一次深拷贝【点击】 | |-> NSArray & NSMutableArray | | NSArray 各种遍历方式,倒序遍历【点击】 | | NSArray简便初始化方法@[@"1",@"2"]; | | 浅拷贝。数组本身使用地址,但是数组item仍是旧对象【Apple 官方解释点击】 | | 无论copy、arrayWithArray、copyWithZone 数组内对象并没有变。 | | 只是copy出来的array是新地址,arrayWithArray出来的数组也是新地址。 | | 深拷贝。数组本身使用地址,但是数组item是新地址 | | [[NSArray alloc] initWithArray:someArray copyItems: YES]; | | 深拷贝时候,数组中的item必须实现NSCopying协议并实现copyWithZone: | | ★防止NSArray was mutated while being enumerated | | array包含array的情况深拷贝。NSArray* trueDeepCopyArray = [NSKeyedUnarchiver \ | | unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]]; | |-> NSDictionary & NSMutableDictionary | | 取值时候,最好判断object的类型。 if ([object isKindOfClass:[NSString class]]){ //todo}; | |-> NSNumber 和 NSInteger NSRange | | 前者专门用来装基础类型的对象,把整型、单精度、双精度、字符型等基础类型存储为对象 | |-> NSNull FMDB数据库,使用的时候崩溃 | | JsonKit转换以后会生出相应的[NSNull null]对象【点击】 | |-> NSData 字节缓冲区 | |-> NSUserDefaults【点击】 | | 可用于APP setting 默认值不好用,SDK bug | | 设置WebVIew的UA【点击】 | |-> NSDate & NSDateFormatter & NSCalendar | | 可判断过去几个小时,还是几天 - (NSDateComponents *) components:fromDate:toDate:options: | | 可获取时间戳 | |-> NSCoding & NSCoder 仅有的两个方法,数据的序列号和反序列化【点击】 | | - (void)encodeWithCoder:(NSCoder *)aCoder; | | - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; | |-> NSCopying & NSZone | | + (instancetype)allocWithZone:深拷贝,类似于memcpy这样的C方法【点击】 | |-> NSAutoreleasePool | | 降低内存峰值【点击】 | |-> NSFileManager 删除文件的时候先判断是否存在是个好习惯 | |-> NSTimer | | NSTimer 简单使用 【点击】 | | ★ NSTimer定时器时间并不精确,类似于公交车进站,堵车就不准时【点击】 | |-> NSLog暴力打印,常用于测试【点击】 | / |-> Foundation | \ | |-> NSIndexPath 链式结构;tableview用的比较多【点击】 | | 初始化 [NSIndexPath indexPathForRow:0 inSection:1]; | |-> NSError 网络变成经常用到 | |-> NSException | |-> NSStringEncoding NSString的编码格式,了解即可【点击】 | |-> NSProgressIndicator | |-> NSBundle 是个目录,包含了程序使用的资源,如图像,声音,编译好的代码,nib文件【点击】 | |-> NSNetServiceBrowser | |-> NSValue 可以包装任意一个对象,可以用NSValue将struct存到NSArray和NSDictionary中。【点击】 | |-> NSURLSession & NSURLSessionTask 【点击】NSURLSession提供的功能: | | 通过URL将数据下载到内存【点击】 | | 通过URL将数据下载到文件系统 | | 将数据上传到指定URL | | 在后台完成上述功能【点击】 | |-> NSURLRequest 包装了网络请求的信息【点击】 | |-> NSInputStream & NSOutputStream socket编程【点击】 | |-> NSPredicate | | 谓语查询,原理和用法都类似于SQL中的where【点击】 | |-> NSLayoutConstraint | |-> NSLock & NSRecursiveLock & NSCondition 多线程锁 | | 最基本的同步锁【点击】 | | @synchronized{//todo} 同样也是同步锁【点击】 | | 事实上信号量也能实现锁的目的,信号量和锁的区别【点击】第二篇【点击】 | |-> NSMethodSignature / | 配合NSInvocation实现消息转发【点击】 iOS |-> NSInvocation 直接调用 某个对象的消息【点击】 \ | iOS中可以直接调用 某个对象的消息 方式有2种performSelector:withObject: 和NSInvocation | |-> NSSet 无序的对象集合,用处少 | |-> NSUrl 基本使用,包含File URL和File path【点击】 | |-> AVPlayer基本使用【点击】 | | 获取视频时间长度 【点击】 | \-> NSNotificationCenter 同步的机制【点击】注意防止重复,相似的机制还有delegate,observer,block | | /-> 创建push原理介绍、证书制作、测试push 专辑 【点击】 | | "iOS push全方位解析(一)【译文】"——iOS PUSH概述【点击】 | | "iOS push全方位解析(二)【译文】"——生成OpenSSL证书,Provisioning Profile【点击】 | | "iOS push全方位解析(三)【译文】"——一个极简的demo,并测试一下push【点击】 | / |-> Push | \ | | ★ iOS6、7、8、9 Push的演化 【点击】,但目前还是不尽人意(APP 无法获取通知栏消息数目) | | ★ php写的可以在本机发送iOS push程序【点击】 | | iOS7 Background Remote Notification(后台远程通知——静默push)【点击】 | \-> 有一些三方push SDK:极光push | |-> block 必须掌握 | block专辑【点击】;Block带有局部变量的匿名函数;iOS开发尤其实用 | 【block编程第一篇】 block编程热点介绍(官方文档翻译的)【点击】 | 【block编程第二篇】 block捕获变量和对象【点击】 | 【block编程第三篇】block内存管理——如何验证block在栈上,还是堆上【点击】 | 【block编程第四篇】block的实现【点击】 | 【block编程第五篇】block中使用 weak–strong dance 技术避免循环引用【点击】 |-> 多线程 | iOS有三种多线程编程的技术,分别是:【点击】 | 1、NSThread 下面会讲到 | 2、Cocoa NSOperation 下面会讲到 | 3、GCD 下面会讲到 | 这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单。 | | /-> 引用计数(retainCount) | | retain 引用计数+1 对象alloc时,引用计数为1, release引用计数-1.引用计数=0时候,真正释放 | | autoRelease,自动释放对象【点击】 | |-> 便捷构造方法 iOS | | 对象在自动释放池中,不需要开发者手动释放,比如下面的方法 | | NSString的stringWithString | | NSArray的arrayWithObjects:和arrayWithArray: | | UIImage的imageNamed: | |-> 内存管理高级指南【官方译点击】 | |-> 内存管理实践【点击】 | / |-> 内存管理【专栏点击】 | \ | |-> MRC 手动引用计数。release和retain成对儿 | \->ARC 自动引用计数 | ★强烈建议使用ARC | ★禁止在函数内返回局部变量指针,不然就是野指针! | ★容易引起循环引用的地方【点击】 | | /-> Runtime 运行时特点 | | objc_setAssociatedObject【点击】给对象增加属性,一般配合类别使用 | | object_getClass 得到一个实例的类【点击】 | | objc_copyImageNames 获取指定类所在动态库【南峰子出品点击】 | | objc_copyClassList 创建并返回一个指向所有已注册类的指针列表【点击】 | | class_xxx系列函数【点击】 | | class_copyPropertyList 获取类的属性 | | class_isMetaClass 判断是否为元类 | | class_getName 获取类名 | | class_copyIvarList 拷贝类的实例变量列表 | | class_getInstanceMethod 获取实例方法 | |-> CFRunnloop 【ibireme出品 点击】 | | RunLoop 实际上就是一个对象,这个对象管理了其需要处理的事件和消息 | | 并提供了一个入口函数来执行上面 Event Loop 的逻辑 | / |-> iOS 动态机制 | \ | |-> 消息传递 objc_msgSend【点击】【南峰子出品 点击】 | | 如果向某对象传递消息,那就会使用动态绑定机制来决定需要调用的方法 | | objc_msgSend有两个隐藏参数,消息接收对象 方法的selector ,即(self,_cmd) | |-> 消息转发 message forwarding【点击】 | | 就是对象在接收到无法解读的消息之后会发生什么情况 | | (1) +(BOOL) resolveInstanceMethod:(SEL)selector 类是否新增一个实例方法 | | (2) resolveClassMethod 是否新增了类方法 | | (3) -(id) forwardingTargetForSelector:(SEL)selector 能不能把这条消息转给其他接收者来注册 | | (4)-(void) forwardInvocation:(NSInvocation*)invocation 消息派发系统 | | (5)最后若都不能处理消息,则doesNotRecognizeSelector: 会抛出异常 | | ★当我们不能确定一个对象是否能接收某个消息时,会先调用respondsToSelector:来判断一下 | |-> 方法调配技术 method swizzling 用于调试【南峰子出品点击】 | | SEL又叫选择器,是表示一个方法的selector的指针,每一个方法都对应着一个SEL。 | | IMP 它是objetive-C 方法(method)实现代码块的地址,实际上是函数指针,指向方法实现的首地址 | | Swizzling应该总是在+load中执行 | \-> 事件响应链【点击】另外一篇【点击】 | 在 iOS 中,几乎所有类都是 responder,比如 UIWindow、UIView、UIControl、UIControllers 等 | 当手指去触摸屏幕上 UIView 的实例对象 aView。产生一个触摸事件 UIEventTypeTouches | 而接收触摸事件的对象 aView,就是一个 responder object。 | initial view –> super view –> …..–> view controller –> window –> Application –> AppDelegate | | /-> 沙盒(Sandbox)iOS沙盒机制【容芳志出品点击】 | | 每个应用程序都有自己的存储空间 | | 应用程序不能翻过自己的围墙去访问别的存储空间的内容 | | 应用程序请求的数据都要通过权限检测,假如不符合条件的话,不会被放行。 | |-> Group iOS8+数据共享,例如扩展(Extension)共享数据【点击】 | |-> Spotlight iOS9+ 系统搜索。【官方demo点击】 | |-> GCD(Grand Central Dispatch) iOS开发有一个强有力的多线程工具 【点击】 | | 多线程入门【raywenderlich出品 点击】 | | 系统提供一个叫做 主队列(main queue) | | 系统还提供一个叫做全局调度队列(Global Dispatch Queues)有四个优先级 | | 开发者自己创建队列(串行,或者并行) | | ★至少有五个队列任你处置:主队列、四个全局调度队列,再加上任何你自己创建的队列。 | | GCD 深入理解:第一部分【点击】 | | GCD 深入理解:第二部分【点击】 | | 开发常见方法介绍 | | dispatch_after 延后工作 | | Dispatch Groups 会在整个组的任务都完成时通知你 | | dispatch_semaphore_t 信号量,让你控制多个消费者对有限数量资源的访问。【点击】 | | dispatch_semaphore_wait 使得信号量-1,当=0时候阻塞 | | dispatch_semaphore_signal 释放信号量,即信号量+1 | | | |-> CoreData数据持久化,相比sqlite有下面优势【点击】 | | 数据库字段或者表有更改会导致crash,CoreData的版本管理和数据迁移变得非常有用,\ | | 手动写sql语句操作还是麻烦一些。 | | 不光能操纵SQLite,CoreData和iCloud的结合也很好,如果有这方面需求的话优先考虑 | | 并不是直接操纵数据库,比如:使用CoreData时不能设置数据库的主键,目前仍需要手动操作。 | | 效率上其实跑程序时感觉不出来,毕竟手机上的数据不能跟网站的数据和访问量相提并论。 | / |->iOS 特殊封装&平台特性 | \ | |-> 类别(Category)扩展(Extension)微小区别【点击】 | | 堪称iOS编程的精髓【点击】 | |-> KVC 键值编码 | | 在IOS的中,没有绝对的私有,包括方法和变量,可以通过字符获取属性【点击】 | |-> KVO 键值观察 | | 依赖Runtime 和KVC 一个新的类会动态被创建。详细原理【点击】另外一篇【点击】 | | ★比如:Tableview上拉下拉动画检测offset;播放视频,获取视频时长时候等 | | 为什么KVO不成对儿调用,会崩溃? | |-> 多任务 | |-> 3D Touch ,通过在plist中添加菜单,然后app实现下面的方法。进入APP | | - (void)application: performActionForShortcutItem: completionHandler: | |-> spotlight 通过系统搜索,进入APP【点击】 | \-> Touch ID 如何使用iOS 8 指纹识别,代码、实例【点击】 | | \-> iOS工具 CrashHlytics Crash统计工具 AFHttp 和 ASIHttp SDImage ------------------------------------------------------------------------------------------ 参考文献:《Objective-C高级编程:iOS与OS X多线程和内存管理》日本人写的; 《Effective Objective C 2.0:编写高质量iOS与OS X代码的52个有效方法》; 《Objective-C基础教程(第2版)》 |
|