http://blog.csdn.net/hherima/article/details/50714866

【精】iOS知识树,知识点(包括对象、Block、消息转发、GCD、运行时、runloop、动画、Push、KVO、tableview,UIViewController、提交AppStore)
  1. 本文旨在总结[iOS](http://lib.csdn.net/base/ios)知识网络,知识点,该知识网络罗列出常见UIKit、Foundation的对象特点和一些使用经验,可以看成是一本书;文本编辑采用树的形式,对知识点进行罗列,并标注一些使用经验(★)希望对初学者有用或给一些解决疑难杂症者提供思路;某些知识点会深入探讨;通过总结希望站在一个较高平台的角度全观[Objective-C](http://lib.csdn.net/base/objective-c)。知识树中有些是原创文章,有些则是转载网络上iOS大神的文章。由于篇幅的限制笔者会简洁地介绍各个知识点,读者可通过链接了解详情。当然一个人的知识面是相当有限的,在给各位读者提供知识参考的同时,欢迎大家对本文提意见。<br /> **/->****UIViewController**<br /> **|** ViewController在iOS只是一个非常重要的概念,其在一个App中所扮演的角色:<br /> **|** (1) View Management:管理View (2) Data Marshalling:管理数据<br /> **|** (3) User Interactions:响应用户交互 (4) Resource Management:管理资源<br /> **|** (5) Adaptivity:适配不同的屏幕尺寸空间的变化<br /> **|** **★** 生命周期【一片枫叶[点击](http://www.cnblogs.com/smileEvday/archive/2012/03/05/2380916.html) 另外一篇[点击](http://blog.csdn.net/huifeidexin_1/article/details/7566226)】<br /> **|** + (void)initialize +(void)load 的调用时机,区别【[点击](http://www.cnblogs.com/ider/archive/2012/09/29/objective_c_load_vs_initialize.html)】<br /> **|** ViewDidLoad调用时机:当view被首次使用的时候,某些情况可提升性能<br /> **|** 横竖屏的坑【[点击](http://www.molotang.com/articles/1530.html)】。APP整体是竖屏,单个controller可以是横屏的<br /> **|** **★** 两种交互方式:push和present<br /> **|** 左右滑动 - (void)pushViewController:(UIViewController *) animated:(BOOL)<br /> **|** 模态,从下往上弹出 - (void)presentViewController:(UIViewController *) animated: (BOOL) completion:<br /> **|** **★**还有一种:直接把Controller的view添加到另一个Controller上。<br /> **|-> UIView<br /> **| ****frame 和bound 的区别【[点击】](http://blog.csdn.net/hherima/article/details/39501857)<br />** | **frame 是相对父试图坐标的值; bound是本身坐标系统的值** <br /> | **layoutSubviews【[点击】](http://bachiscoding.com/blog/2014/12/15/when-will-layoutsubviews-be-invoked/) 需要将[super layoutSubviews];放到最后,不然iOS7有可能会有这个崩溃<br />** ****| ★ **"Auto Layout still required after executing -layoutSubviews” iOS7上崩溃sdk缺陷 【[点击】](http://blog.csdn.net/hherima/article/details/47343223)<br />** ****| layoutSubviews在以下情况下会被调用:**<br />** ****| **1、init初始化不会触发layoutSubviews。<br />** ****| **2、addSubview会触发layoutSubviews。<br />** ****| **3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。<br />** ****| **4、滚动一个UIScrollView会触发layoutSubviews。<br />** ****| **5、旋转Screen会触发父UIView上的layoutSubviews事件。<br />** ****| **6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。<br />** ****| **7、直接调用setLayoutSubviews。<br />** ****| **每一个视图有唯一的父视图【[点击】](https://www.google.com.hk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwiy5O3Rw43LAhVC6aYKHZKODkUQFggaMAA&url=http%3A%2F%2Fblog.csdn.net%2Flikendsl%2Farticle%2Fdetails%2F7877648&usg=AFQjCNFcaySH69-7iD1eURhgCvzkEZeq6g)。addsubview操作把它从上一个父试图中移除<br />** ****| **善于使用hidden 使用animateWithDuration简单地控制页面切换效果<br />** ****| **使用animateWithDuration简单地控制页面切换效果【[点击](http://blog.csdn.net/baxiaxx/article/details/7732991)】<br />** ****| ★**简单动画 animateWithDuration【[点击](http://www.jianshu.com/p/bd7bf438b288)】<br /> **|->CALayer**<br />** ****| **CALayer是个简单的类,它是用来在屏幕上显示内容展示的矩形区域.【容芳志出品[点击](http://blog.csdn.net/totogo2010/article/details/8605092)】<br />** ****| **直接从NSObject继承,少了UIResponder类,固CALayer悲催的不能响应任何用户事件【[点击](http://o0o0o0o.iteye.com/blog/1728599)】<br /> **|-> UIWindow<br /> | **每一个IOS程序都有一个UIWindow<br />** | **UIWindow有三个层级,分别是Normal,StatusBar,Alert【[点击】](http://www.cnblogs.com/smileEvday/archive/2012/11/16/UIWindow.html)<br />** ****| **keyWindow是指定的用来接收键盘以及非触摸类的消息,<br />** ****| **而且程序中每一个时刻只能有一个window是keyWindow。<br />** ****|-> ****UIImage**<br />** ****| **加载图片几种方式【[点击】](http://blog.csdn.net/wzzvictory/article/details/9053813)<br />** ****| **[UIImage imageNamed:@“xxx”] 系统缓存到cache中<br />** ****| ** [UIImage imageWithContentsOfFile:path] 不缓存<br />** ****| ** [UIImage imageWithData:data] 不缓存<br />** ****| ★ **拉伸图片,四角保持不变** **resizableImageWithCapInsets:<br />** ****| ** **★ **加载gif图片【[点击】](http://blog.csdn.net/hherima/article/details/50721594)<br />** ****|-> ****UILabel【**[点击】](http://www.cnblogs.com/aipingguodeli/archive/2012/04/05/2433040.html)<br />** ****| **** **没有居上居下对齐,可以使用TTTAttributedLabel<br />** ****| **** **★ ** **重写drawTextInRect:方法,可以自定义绘制区域,比如可设置Inset<br />** ****| **** **[super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.textInsets)];<br /> **/** <br />** **/->** UIKit <br /> | **\** <br /> **|** |-> UIButton**<br />** **|** ****| **** **设置颜色,文字一定要指定button状态<br />** **|** ****| **** **★****善于使用contentEdgeInsets,imageEdgeInsets titleEdgeInsets可以设置文本边距【[点击】](http://www.cnblogs.com/objectc/p/4560032.html)<br />** | ****| **** **设置圆角可layer.cornerRadius<br />** | ****| **** **★****UIButton 设置 imageView frame是无法改变大小的,大小就是图片的大小[【点击】](http://blog.csdn.net/richaolas/article/details/44726915)<br />** | ****| **** **设置button上的title左对齐。仅仅设置label是没用的,需要:<br />** | ****| **** **★ ****btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;<br />** **|****** **** |-> UITextfield <br /> **|****** **** ****| **隐藏键盘,[textfield resignFirstResponder]<br />** **|****** **** ****| **★ 任意页面隐藏键盘【[点击】](http://blog.csdn.net/hherima/article/details/50717161)<br />** |**** **** |-> UIScrollerView<br /> |**** **** ****| **上拉下拉原理【[点击](http://blog.csdn.net/hherima/article/details/44924319)】<br />** **|****** **** |-> UITableView<br /> **|****** **** ****| **复用,注意重写 - (void)prepareForReuse<br />** |**** **** ****| ★ **在-(void)layoutSubviews中设置subview的frame。否则frame总是(320,44)<br />** |**** **** ****| **dequeueReusableCellWithIdentifier 从重用池中获取,可能是nil<br />** |**** **** ****| **dequeueReusableCellWithReuseIdentifier 同上,但是不会是nil<br />** |**** **** ****| **插入,删除,移动section或item的顺序,需遵循下面两个步骤【[点击](https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCellsandViews/CreatingCellsandViews.html#//apple_ref/doc/uid/TP40012334-CH7-SW7)】<br />** |**** **** ****| **1. 更新dataSource的数据<br />** |**** **** ****| **2. 调用相应的collection view方法删除或者插入section或item<br />** |**** **** ****| ★**非常严格的条件:,在更新collection view之前,先更新datasource,<br />** |**** **** ****| **因为collection view总是假设你已经准备好打他source了 否则collection view收到错误的item,并造成crash<br />** **|****** **** ****| **右侧音序条【[点击】](http://blog.csdn.net/hherima/article/details/39929523)<br />** |**** **** ****| **UITableView上拉、下拉原理【[点击】](http://blog.csdn.net/hherima/article/details/44924319)<br />** |**** **** ****| **AsyncDisplayKit 流畅的解决方法【[点击](https://github.com/facebook/AsyncDisplayKit)】<br />** |**** **** **| **★**tableView正在滚动的时候,如果reloadData,偶尔发生App crash的情况【[点击](http://www.cocoachina.com/bbs/read.php?tid=81462)】<br />** |**** **** **| **★**UITableview Deceleration 加速滑动(惯性滑动)、弹性回归原理【[点击](http://blog.csdn.net/hherima/article/details/8694914)】<br />** |**** **** **| **★**UITableview 刷新某一个cell 或 section【[点击](http://blog.sina.com.cn/s/blog_6c9d5da50101fdw3.html)】<br />** |**** **** **| **★**UITableview 上拉隐藏搜索框,下拉出现搜索框【[点击](http://www.jianshu.com/p/bfc5d4f6128e)】<br />** |**** **** **| **★**UITableview 是在willDisplayCell: 还是在cellForRowAtIndexPath: update data 呢?[【点击】](http://stackoverflow.com/questions/31988450/ios-uitableview-whats-the-different-between-cellforrowatindexpath-and-willd)<br />** |**** **** **| **★**UITableview UITableViewStylePlain模式,header不浮动【[点击](http://blog.csdn.net/hherima/article/details/51030113)】<br /> **|** ** |-> UIDevice<br /> **|** ****| **设备名 [UIDevice currentDevice].name,<br />** **|** **** | **系统版本号 [[UIDevice currentDevice].systemVersion doubleValue]; 【[点击】](http://blog.csdn.net/hherima/article/details/46409247)<br />** **|** **** | **屏幕旋转方向 [[UIDevice currentDevice] orientation]<br />** **|** **** ****| **区分iPad还是iPhone [UIDevice currentDevice].userInterfaceIdiom);<br />** **|** **|******-> ****UIScreen<br /> **|** ** **|** 如何正确的绘制1像素的线【[点击】](http://blog.csdn.net/hherima/article/details/46679157)<br />** | ** **|** 保证边距不变,内容等比例拉伸【[点击】](http://blog.csdn.net/hherima/article/details/50724704)<br />** | ** **|****-> ****UIEdgeInsets<br /> | **|** **实际显示边距,跟设置边距的距离【[点击](http://blog.sina.com.cn/s/blog_7c8dc2d50101l1h2.html)】<br />** ****|**** **** ****\****->****自动布局<br /> | **Masonry 高级一点用法【多个label,可变长情况下使用Masonry】【[点击](http://blog.csdn.net/hherima/article/details/53318306)】<br />** | **storyboard<br />** |**<br />** ****|**** ****/-> NSObject** 既是对象也是协议,可以将对象自动置nil 比如 int = 0 bool = NO<br /> **|** **|** 几乎所有类的基类或者协议【[点击](http://blog.csdn.net/minkowsky/article/details/4270212)】<br /> **|** **|** isKindOfClass:和isMemberOfClass:,通过这两种方法可以确定一个类的从属关系\<br /> **|** **|** 后者[测试](http://lib.csdn.net/base/softwaretest)一个接收器是否是一个指定类的实例;而后者可以测试类的从属关系。<br /> **|** ** ****|** respondsToSelector: 方法测试一个接收器是否通过selector实现(implements)了一个标志符话的方法<br /> **|** **|** description方法,允许一个对象返回一个字符串来描述它的内容;这个常用于调试debug<br /> **|** **|** encodeWithCoder: 和 initWithCoder:方法,NSCoding协议中仅有的组成成员\<br /> **|** **|** 第一个允许对象编译它的实例变量,第二个允许一个对象初始化它自身的解码实例变量。<br /> **|** **|** conformsToProtocol:方法,测试接收器(对象或者类)符合一个给定的协议(protocol)<br /> **|** **|** **★**类对象中的 isa 指向类结构被称作 metaclass【点击】跟[object class]有点区别,比如KVO的时候<br /> **|** **|** **★**__weak如何实现对象值自动设置为nil的【[点击](http://blog.csdn.net/hherima/article/details/38661803)】<br /> **|** **|**->****** ****NSString & NSMutableString<br /> **|** **|** **NSString作为属性时候,用copy还是strong修饰?<br />** **|** **|** **strong是单纯的增加对象的引用计数,而copy操作是执行了一次深拷贝【[点击】](http://www.cocoachina.com/ios/20150512/11805.html)<br /> **|** **|******->**** **NSArray & NSMutableArray<br /> | **|**** NSArray 各种遍历方式,倒序遍历【[点击】](http://blog.csdn.net/hherima/article/details/38470173)<br />** ****| **|****** **NSArray简便初始化方法@[@"1",@"2"];<br />** ****| |**** **浅拷贝。数组本身使用地址,但是数组item仍是旧对象【Apple 官方解释[点击](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Collections/Articles/Copying.html)】<br />** ****| |**** **无论copy、arrayWithArray、copyWithZone 数组内对象并没有变。<br />** ****| |**** **只是copy出来的array是新地址,arrayWithArray出来的数组也是新地址。<br />** ****| |**** **深拷贝。数组本身使用地址,但是数组item是新地址<br />** ****| |**** **[[NSArray alloc] initWithArray:someArray copyItems: YES]; <br />** ****| |**** **深拷贝时候,数组中的item必须实现NSCopying协议并实现copyWithZone:<br />** ****| **|****** ****★**防止NSArray was mutated while being enumerated<br />** ****| |**** **array包含array的情况深拷贝。NSArray* trueDeepCopyArray = [NSKeyedUnarchiver \** **<br />** | |**** **unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]];<br />** ****| |**** ****★**containsObject 注意:在对比数组中元素的时候,调用元素的isEqual的返回值。<br />** | **|****->** NSDictionary & NSMutableDictionary**<br />** ****| **|****** **取值时候,最好判断object的类型。 if ([object isKindOfClass:[NSString class]]){ //todo};<br />** | **|****->** NSNumber 和 NSInteger NSRange**<br />** **| | 前者专门用来装基础类型的对象,把整型、单精度、双精度、字符型等基础类型存储为对象<br />** | **|****-> **NSNull** FMDB[数据库](http://lib.csdn.net/base/mysql),使用的时候崩溃<br />** | | ** JsonKit转换以后会生出相应的[NSNull null]对象【[点击](http://blog.csdn.net/hherima/article/details/10335591)】<br />** | **|****->** NSData **字节缓冲区<br />** | | **+ (nullable instancetype)dataWithContentsOfURL:(NSURL *)url<br />** | | **dataWithContentsOfURL 虽然是同步的,但可以结合gcd 异步加载网络图片【[点击](http://blog.csdn.net/mad1989/article/details/8674962)】<br />** ****| **|********->** ****NSUserDefaults【[点击](http://blog.csdn.net/zhangzhebjut/article/details/24050671)】**<br />** ****| | **** **可用于APP setting** **默认值不好用,SDK bug <br />** ****| | **** **设置WebVIew的UA【[点击](http://blog.csdn.net/hherima/article/details/50599285)】<br />** ****| **|********->** ****NSDate & NSDateFormatter & NSCalendar****** ****| |**** **可判断过去几个小时,还是几天 - (NSDateComponents *) components:fromDate:toDate:options:<br />** ****| |**** **可获取时间戳<br />** ****| |**** **有时候有8小时的时差,解决办法【[点击](http://blog.csdn.net/shijiucdy/article/details/7579612)】<br />** ****| |**** **在开发iOS程序时对日期处理的总结【[点击](http://kevin-wu.net/tag/nsgregoriancalendar/)】<br />** ****| **|********->** ****NSCoding & NSCoder **仅有的两个方法,数据的序列号和反序列化【[点击](http://www.cnblogs.com/xiaofeixiang/p/4266156.html)】 <br />** ****| ****| **- (void)encodeWithCoder:(NSCoder *)aCoder;<br />** **| | - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;<br />** | **|****->** NSCopying & NSZone**<br />** **| **|** + (instancetype)allocWithZone:深拷贝,类似于memcpy这样的C方法【[点击](http://vin-zhou.github.io/2014/11/17/%E6%8E%A2%E7%A9%B6Objective-C-%E4%B9%8B%E6%B7%B1%E6%B5%85%E6%8B%B7%E8%B4%9D/)】<br />** | **|****->** NSAutoreleasePool**<br />** **| | 降低内存峰值【[点击](http://eleda.iteye.com/blog/1108700)】<br />** **| | 在Runloop休眠前(kCFRunLoopBeforeWaiting)时候释放自动释放池中的对象<br />** ****| **|****->** ****NSFileManager** 删除文件的时候先判断是否存在是个好习惯<br />** | **|********->** ****NSTimer<br /> | **|****** **NSTimer 简单使用 【[点击】](http://blog.csdn.net/hherima/article/details/8670619)<br />** | **|****** ★ **NSTimer定时器时间并不精确,类似于公交车进站,堵车就不准时【[点击】](http://blog.csdn.net/hherima/article/details/50681498)<br />** | **|********->** ****NSLog**暴力打印,常用于测试【[点击](http://www.cnblogs.com/qingyuan/p/3524791.html)】<br />** | |****->** **NSClassFromString** 从字符串获取类。**NSStringFromClass**,从类名获取字符串<br />** | | **★ ****不要小瞧这两个API,配合使用,他可以做到代码逻辑解藕的效果。<br /> **|** **/** <br /> **|-> ****Foundation <br /> | \** <br />** ****| **|********->** ****NSIndexPath** 链式结构;tableview用的比较多【[点击】](http://lixiangyu.iteye.com/blog/1620266)<br />** ****| | **初始化 [NSIndexPath indexPathForRow:0 inSection:1];<br />** ****| **|********->** ****NSError** 网络变成经常用到<br />** ****| **|********->** **NSException<br />** ****| **|********->** **NSStringEncoding NSString的编码格式,了解即可【[点击](http://blog.csdn.net/nextj/article/details/8296414)】<br />** ****| **|********->** **NSProgressIndicator<br />** ****| **|********->** **NSBundle 是个目录,包含了程序使用的资源,如图像,声音,编译好的代码,nib文件【[点击】](http://blog.csdn.net/totogo2010/article/details/7672271)<br />** ****| **|********->** **NSNetServiceBrowser<br />** ****| **|********->** ****NSValue **可以包装任意一个对象,可以用NSValue将struct存到NSArray和NSDictionary中。【[点击】](http://blog.csdn.net/at9009/article/details/7863720)<br />** ****| |****-> ****NSURLConnection **iOS9已不再使用<br />** ****| **|********->** ****NSURLSession** & **NSURLSessionTask** 【[点击】](http://objccn.io/issue-5-4/)NSURLSession提供的功能:<br />** **| **|** 通过URL将数据下载到内存【[点击】](http://www.cnblogs.com/biosli/p/iOS_Network_URL_Session.html)<br />** **| | 通过URL将数据下载到文件系统<br />** **| | 将数据上传到指定URL<br />** **| | 在后台完成上述功能【[点击】](http://www.jianshu.com/p/045cdfdaaf6e)<br />** ****| **|********->** **NSURLRequest 包装了网络请求的信息【[点击】](http://blog.csdn.net/kylinbl/article/details/6590099)<br />** ****| **|********->** **NSInputStream & NSOutputStream socket编程【[点击】](http://www.cnblogs.com/kesalin/archive/2013/04/29/ios_network_nsstream.html) <br />** ****| **|********->** ****NSPredicate** <br />** **| | 谓语查询,原理和用法都类似于SQL中的where【[点击](http://www.cnblogs.com/thefeelingofsimple/archive/2013/01/31/2886915.html)】<br />** ****| **|********->** **NSLayoutConstraint**<br /> | **|****->** NSLock & NSRecursiveLock & NSCondition **多线程锁<br />** **| **|** 最基本的同步锁【[点击](http://www.cnblogs.com/sunfrog/p/3247361.html)】<br />** **| **|** @synchronized{//todo} 同样也是同步锁【[点击】](http://www.cnblogs.com/apem/p/4633790.html)<br />** **| **|** 事实上信号量也能实现锁的目的,信号量和锁的区别【[点击](http://www.cnblogs.com/diyingyun/archive/2011/12/04/2275229.html)】第二篇【[点击](http://www.eetop.cn/blog/html/04/343504-14125.html)】<br />** ****|**** **|****->** NSMethodSignature** ** **<br /> **/** **|**** **配合NSInvocation实现消息转发【[点击】](http://blog.csdn.net/freshforiphone/article/details/7381329)<br />**iOS ****|******->****** ****NSInvocation **直接调用 某个对象的消息【[点击】](http://www.cnblogs.com/pengyingh/articles/2359199.html)<br />** ****\**** ****| ** iOS中可以直接调用 某个对象的消息 方式有2种performSelector:withObject: 和NSInvocation<br />** **|** ****| ** 当然,还以用[C语言](http://lib.csdn.net/base/c)的函数指针,参见下面的“**方法调配技术**”<br />** ****|**** **|********->** ****NSSet **无序的对象集合,用处少<br />** **|** **|********->** ******NSUrl****** **基本使用,包含File URL和File path【[点击](http://www.cnblogs.com/tara/archive/2013/03/20/2970531.html)】<br />** | |****-> ****AVPlayer**基本使用【[点击】](http://www.programering.com/a/MzN1IDNwATY.html)<br /> **|** **|** 获取视频时间长度 【[点击】](http://stackoverflow.com/questions/8181533/how-do-i-get-current-playing-time-and-total-play-time-in-avplayer)<br />** ****|**** ****\****->**** ****NSNotificationCenter** 同步的机制【[点击](http://blog.csdn.net/hherima/article/details/50395429)】注意防止重复,相似的机制还有delegate,observer,block<br />** ****|****<br /> | **/->** 创建push原理介绍、证书制作、测试push 专辑** 【[点击】](http://blog.csdn.net/column/details/ios-push-hherima.html)<br /> **| | **"iOS push全方位解析(一)【译文】"——iOS PUSH概述【[点击](http://blog.csdn.net/hherima/article/details/45583787)】<br /> **| **|** **"iOS push全方位解析(二)【译文】"——生成OpenSSL证书,Provisioning Profile【[点击】](http://blog.csdn.net/hherima/article/details/45583865)<br /> **| **|** **"iOS push全方位解析(三)【译文】"——一个极简的demo,并测试一下push【[点击】](http://blog.csdn.net/hherima/article/details/45624075)<br /> **| **/**<br /> |-> Push <br /> | **\**<br /> | **|** **★ iOS6、7、8、9 Push的演化 【[点击】](http://blog.csdn.net/hherima/article/details/50469670),但目前还是不尽人意(APP 无法获取通知栏消息数目)<br /> **| **|** ★ **[PHP](http://lib.csdn.net/base/php)写的可以在本机发送iOS push程序【[点击】](http://blog.csdn.net/hherima/article/details/50470409)<br /> **| **|** **iOS7 Background Remote Notification(后台远程通知——静默push)【[点击】](http://blog.csdn.net/hherima/article/details/50469519)<br />** ****|**** \-> 有一些三方push SDK:极光push<br /> **|**<br />** **|****->**** b****lock **必须掌握<br />** ****|**** **block专辑【[点击】](http://blog.csdn.net/column/details/block.html);Block带有局部变量的匿名函数;iOS开发尤其实用<br />** | **【block编程第一篇】 block编程热点介绍(官方文档翻译的)【[点击](http://blog.csdn.net/hherima/article/details/17352053)[】](http://blog.csdn.net/hherima/article/details/38586101)<br />** | **【block编程第二篇】 block捕获变量和对象【[点击](http://blog.csdn.net/hherima/article/details/45313211)[】](http://blog.csdn.net/hherima/article/details/38586101)<br />** | **【block编程第三篇】block内存管理——如何验证block在栈上,还是堆上【[点击】](http://blog.csdn.net/hherima/article/details/38586101)<br />** | **【block编程第四篇】block的实现【[点击](http://blog.csdn.net/hherima/article/details/38586101)[】](http://blog.csdn.net/hherima/article/details/38586101)<br />** | **【block编程第五篇】block中使用 weak–strong dance 技术避免循环引用【[点击](http://blog.csdn.net/hherima/article/details/45313877)[】](http://blog.csdn.net/hherima/article/details/38586101)<br />** **|****->** **多线程****<br />** ****| **iOS有三种多线程编程的技术,分别是:【[点击](http://blog.csdn.net/totogo2010/article/details/8010231)】<br />** ****| **1、NSThread 下面会讲到<br />** ****| **2、Cocoa NSOperation 下面会讲到<br />** ****| **3、GCD 下面会讲到<br />** ****|** 这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单。<br />** ****| **dispatch_once 执行一次,用于创建单例【[点击](http://blog.csdn.net/marsdoudouluo/article/details/8190650)】可满足线程安全<br />** ****| ** iOS 不像C++ 那样,可以直接将构造函数设成private**。**所以创建绝对单例模型需重写allocWithZone,【[点击](http://straybirdzls.github.io/blog/2014/10/28/arc/)】<br />** ****|** <br /> **| /-> 引用计数**(retainCount)<br /> **|**** ****| ** retain 引用计数+1 对象alloc时,引用计数为1, release引用计数-1.引用计数=0时候,真正释放<br /> **|**** ****| ** autoRelease,自动释放对象【[点击](http://blog.csdn.net/hherima/article/details/8776538)】<br /> **|**** **|****-> **便捷构造方法 iOS**<br /> **|**** | **对象在自动释放池中,不需要开发者手动释放,比如下面的方法<br /> **|**** | **NSString的stringWithString<br /> **|**** | **NSArray的arrayWithObjects:和arrayWithArray:<br /> **|**** | **UIImage的imageNamed:<br /> **|**** |-> 内存管理高级指南**【官方译[点击](http://blog.csdn.net/hherima/article/details/16355591)】<br /> **|**** |-> ****内存管理实践**【[点击](http://blog.csdn.net/hherima/article/details/16355819)】<br /> **|**** ****/**<br /> **|->** **内存管理【专栏[点击](http://blog.csdn.net/column/details/memory-management-hh.html)】<br /> | \<br /> | |-> MRC** 手动引用计数。release和retain成对儿<br /> **|** **\******->******ARC** 自动引用计数<br /> **|** ** ★**强烈建议使用ARC<br /> **|** ** ★**禁止在函数内返回局部变量指针,不然就是野指针!<br /> **|** ** ** ★容易引起循环引用的地方【[点击](http://blog.csdn.net/hherima/article/details/39078545)】<br /> **|** ** ** ★- (id)performSelector:(SEL)aSelector withObject:(id)object;引起警告<br /> **|** ** ** warning:performSelector may cause a leak because its selector 【[点击](http://www.07net01.com/program/548732.html)】<br /> **|**<br /> **|->** **进程间通信(APP间通信)**【[点击](http://blog.csdn.net/lifengzhong/article/details/7739539)】【[点击](http://www.cnblogs.com/liuhao-0627/p/4304904.html)】<br />** ****| **iOS可通过URL Scheme,调用别的APP(iOS内的应用调用协议),APP 实现 - (BOOL)application: openURL: options: <br />** ****|**<br />** ****|**** ****/****->** **Runtime** 运行时特点【《运行时之一:类与对象》南峰子出品 [点击](http://southpeak.github.io/blog/2014/10/25/objective-c-runtime-yun-xing-shi-zhi-lei-yu-dui-xiang/)】<br />** | **| ****Objective-C程序员可以在程序运行时创建,检 查,修改类,对象和它们的方法【[点击](http://www.jianshu.com/p/970ae3bac1ef)】<br />** | ****| **Objective-C runtime库也负责找出方法的最终执行代码<br />** |** **| ****★**class Objective-C类是由Class类型来表示的,它实际上是一个指向objc_class结构体的指针。<br />** |** **| **struct objc_class {<br />** |** **| ** Class isa OBJC_ISA_AVAILABILITY;<br />** |** **| **#if !__OBJC2__<br />** |** **| ** ** **** **Class super_class OBJC2_UNAVAILABLE; // 父类<br />** |** **| ** ** **** ** const char *name OBJC2_UNAVAILABLE; // 类名<br />** |** **| ** ** **** **long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0<br />** |** **| ** ** **** ** long info OBJC2_UNAVAILABLE; // 类信息,供运行期使用的一些位标识<br />** |** **| ** long instance_size OBJC2_UNAVAILABLE; // 该类的实例变量大小<br />** |** **| ** struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 该类的成员变量链表<br />** |** **| ** struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定义的链表<br />** |** **| ** struct objc_cache *cache ** **OBJC2_UNAVAILABLE; // 方法缓存<br />** |** **| ** struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 协议链表<br />** |** **| **#endif<br />** |** **| **} OBJC2_UNAVAILABLE; <br />** |** **| 1. **isa:所有的类自身也是一个对象,这个对象的Class里面也有一个isa指针,它指向metaClass<br />** |** **| ****2. **super_class:指向该类的父类,如果该类已经是最顶层的根类,则super_class为NULL。<br />** |** **| ****3. **cache:用于缓存最近使用的方法。提高方法查找效率<br />** |** **| ****★****objc_object与id** objc_object是表示一个类的实例的结构体<br />** |** **| **struct objc_object {<br />** |** **| ** Class isa OBJC_ISA_AVAILABILITY;<br />** |** **| **};<br />** |** **| **typedef struct objc_object *id;<br />** |** **| **当创建一个类的实例对象时,分配的内存包含objc_object[数据结构](http://lib.csdn.net/base/datastructure),然后是类的实例变量的数据。<br />** |** **| **NSObject类的alloc和allocWithZone:方法使用函数class_createInstance来创建objc_object数据结构。<br />** |** **| **另外还有我们常见的id,它是一个objc_object结构类型的指针<br />** |** **| ****★****meta class**元类,是一个类对象的类;它存储着一个类的所有类方法。<br />** |** **| **当我们向一个对象发送消息时,runtime会在这个对象所属的这个类的方法列表中查找方法;<br />** |** **| **而向一个类发送消息时,会在这个类的meta-class的方法列表中查找。<br />** |** **| ****★继承体系【[点击](http://www.sealiesoftware.com/blog/class%20diagram.pdf)】<br /> | ****| **动态创建类【[点击](http://www.cppblog.com/kesalin/archive/2012/01/30/objc_create_class.html)】<br />** |** **| **objc_setAssociatedObject【[点击】](http://blog.csdn.net/hherima/article/details/45070771)给对象增加属性,一般配合类别使用** <br /> |** **| **object_getClass 得到一个实例的类【[点击](http://blog.csdn.net/lvdezhou/article/details/49509923)】<br />** |** **| **objc_copyImageNames 获取指定类所在动态库【南峰子出品[点击](http://southpeak.github.io/blog/2014/11/09/objective-c-runtime-yun-xing-shi-zhi-liu-:shi-yi/)】<br />** |** **| **objc_copyClassList 创建并返回一个指向所有已注册类的指针列表【[点击](http://www.kuqin.com/shuoit/20150402/345537.html)】<br />** |** **| ****class_xxx**系列函数【[点击](http://blog.devwu.com/develop/2014-08-17/objcruntime-explore2/)】<br />** |** **| **class_copyPropertyList 获取类的属性<br />** |** **| **class_addMethod 为类添加方法 <br />** |** **| **class_isMetaClass 判断是否为元类<br />** |** **| **class_getName 获取类名<br />** |** **| **class_copyIvarList 拷贝类的实例变量列表<br />** |** **| **class_getInstanceMethod 获取实例方法<br />** ****|**** ****|->**** Runnloop **【ibireme出品 [点击](http://blog.ibireme.com/2015/05/18/runloop/)】<br />** |** **| **RunLoop 实际上就是一个对象,这个对象管理了其需要处理的事件和消息<br />** |** **| **并提供了一个入口函数来执行上面 Event Loop 的逻辑<br />** |** **| **Run Loop并非iOS平台专属的概念,在任何平台的多线程编程中,为控制线程生命周期【[点击](http://oncenote.com/2015/03/22/Threading-Run-Loop/)】<br />** |** **| **接收处理异步消息,都需要类似Run Loop的循环机制来实现:从简单的一个无限顺序<br />** |** **| **do{sleep(1);//执行消息}while(true),到高级平台,如[Android](http://lib.csdn.net/base/android)的Looper,都是类似的机制。<br />** ****|**** ****| ****Runnloop基本作用 **【[点击](http://www.jianshu.com/p/cf4915508929)】<br />** |** **| **·保持程序的持续运行(比如主运行循环)<br />** |** **| ·**处理App中的各种事件(比如触摸事件、定时器事件、Selector事件)<br />** |** **| ·**节省CPU资源,提高程序性能:该做事时做事,该休息时休息<br />** ****|**** ****| ****Runnloop应用**<br />** |**** ****| ·NSTimer** 默认是NSDefaultRunLoopMode,滑动时候定时器不计时<br />** |**** ****| ·ImageView**显示 当用户在拖拽时(UI交互时)不显示图片,拖拽完成时显示图片<br />** |**** ****| ·PerformSelector** 设置运行模式<br />** |**** ****| ·常驻线程** 经常在后台进行耗时操作,如:监控联网状态,扫描沙盒等 不希望线程处理完事件就销毁,保持常驻状态<br />** |**** ****| ·自动释放池** 在休眠前(kCFRunLoopBeforeWaiting)进行释放,处理事件前创建释放池,中间创建的对象会放入释放池<br />** |** **| **★****PerformSelecter 当调用 NSObject 的 performSelecter:afterDelay: 后,实际上其内部会创建一个 Timer<br />** |** **| ** 并添加到当前线程的 RunLoop 中;所以如果当前线程没有 RunLoop,则这个方法会失效【[点击](http://www.cocoachina.com/ios/20150601/11970.html)】<br />** |** **/**<br /> **|->** **iOS 动态机制<br /> | \ <br /> | |-> 消息传递** objc_msgSend【[点击](http://blog.csdn.net/hherima/article/details/38425605)】【南峰子出品 [点击】](http://southpeak.github.io/blog/2014/11/03/objective-c-runtime-yun-xing-shi-zhi-san-:fang-fa-yu-xiao-xi-zhuan-fa/)<br />** | | ** obj-c脱胎于smalltalk的消息处理。所有方法调用都是发消息。消息是啥?一串字符【[点击](https://www.zhihu.com/question/20224364)】<br />** | | ** 如果向某对象传递消息,那就会使用动态绑定机制来决定需要调用的方法<br />** | | ** objc_msgSend有两个隐藏参数,消息接收对象 方法的selector ,即(self,_cmd)<br />** | |-> 消息转发** message forwarding【[点击】](http://blog.csdn.net/hherima/article/details/38425605)** **<br />** |**** ****| **就是对象在接收到无法解读的消息之后会发生什么情况<br />** ****|**** ****| **(1) +(BOOL) resolveInstanceMethod:(SEL)selector 类是否新增一个实例方法<br />** ****|**** ****| **(2) resolveClassMethod 是否新增了类方法<br />** ****|**** ****| **(3) -(id) forwardingTargetForSelector:(SEL)selector 能不能把这条消息转给其他接收者来注册 <br />** ****|**** ****| **(4)-(void) forwardInvocation:(NSInvocation*)invocation 消息派发系统<br />** ****|**** ****| **(5)最后若都不能处理消息,则doesNotRecognizeSelector: 会抛出异常<br />** ****|**** **| **★**当我们不能确定一个对象是否能接收某个消息时,会先调用respondsToSelector:来判断一下<br />** **|** **|->** SEL【[点击](http://www.cnblogs.com/yaski/archive/2009/04/05/1429735.html)】**<br />** ****|**** ****| **SEL又叫选择器,是表示一个方法的selector的指针,每一个方法都对应着一个SEL。<br />** ****|**** ****| **OC在编译的时候,会根据方法的名字(包括参数序列),生成一个用 来区分这个方法的唯一的一个ID<br />** ****|**** ****| ****这个ID就是SEL类型的**。需要注意的是,只要方法的名字(包括参数序列)相同,那么它们的ID都是相同的。<br />** ****|**** ****| **就是 说,不管是超类还是子类,不管是有没有超类和子类的关系,只要名字相同那么ID就是一样的<br />** ****|**** ****| **★****方法的定义体里面,我们可以通过访问_cmd得到这个方法自己的SEL。 <br />** | |-> 方法调配技术** method swizzling 用于调试【南峰子出品[点击】](http://southpeak.github.io/blog/2014/11/06/objective-c-runtime-yun-xing-shi-zhi-si-:method-swizzling/)<br />** ****|**** ****| **IMP 它是objetive-C 方法(method)实现代码块的地址,实际上是函数指针,指向方法实现的首地址<br />** |** **| **IMP imp = [requestItem.delegateTarget methodForSelector:selector];<br />** |** **| **void (*func)(id, SEL, ResponseItem *) = (void *)imp;<br />** |** **| **func(requestItem.delegateTarget, selector, responseItem);<br />** ****|**** ****| **可以从selector获取IMP,比如:- (IMP)methodForSelector:(SEL)aSelector;<br />** ****|**** ****| **Swizzling应该总是在+load中执行<br /> **|** **\->** **事件响应链**【[点击](https://www.zybuluo.com/MicroCai/note/66142)】另外一篇【[点击](http://zhoon.github.io/ios/2015/04/12/ios-event.html)】<br />** ****|**** **** **在 iOS 中,几乎所有类都是 responder,比如 UIWindow、UIView、UIControl、UIControllers 等<br />** ****|**** **** **当手指去触摸屏幕上 UIView 的实例对象 aView。产生一个触摸事件 UIEventTypeTouches<br />** ****|**** **** **而接收触摸事件的对象 aView,就是一个 responder object。<br />** ****|**** **** **initial view –> super view –> …..–> view controller –> window –> Application –> AppDelegate<br /> **| <br /> |** **/****-> ****沙盒(Sandbox)**iOS沙盒机制【容芳志出品[点击](http://blog.csdn.net/totogo2010/article/details/7669837)】<br />** | ****| **每个应用程序都有自己的存储空间<br />** | ****| **应用程序不能翻过自己的围墙去访问别的存储空间的内容<br />** | ****| **应用程序请求的数据都要通过权限检测,假如不符合条件的话,不会被放行。<br />** |** **|****-> ****Group **iOS8+数据共享,例如扩展(Extension)共享数据【[点击](http://www.itiger.me/?p=181)】<br />** |** **|****-> ****Spotlight **iOS9+ 系统搜索。【官方demo[点击](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/AppContent.html#//apple_ref/doc/uid/TP40016308-CH7-SW1)】<br />** |** **|****-> GCD(Grand Central Dispatch)** iOS开发有一个强有力的多线程工具 【[点击](http://blog.csdn.net/hherima/article/details/38843965)】<br />** | ****| **多线程入门【raywenderlich出品 [点击】](http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial)** <br /> | ****| **系统提供一个叫做 主队列(main queue)<br />** | ****| **系统还提供一个叫做全局调度队列(Global Dispatch Queues)有四个优先级<br />** | ****| **开发者自己创建队列(串行,或者并行)<br />** | ****| ★**至少有五个队列任你处置:主队列、四个全局调度队列,再加上任何你自己创建的队列。<br />** | **|** **GCD 深入理解:第一部分【[点击】](https://github.com/nixzhu/dev-blog/blob/master/2014-04-19-grand-central-dispatch-in-depth-part-1.md)<br />** | ****| **GCD 深入理解:第二部分【[点击】](https://github.com/nixzhu/dev-blog/blob/master/2014-05-14-grand-central-dispatch-in-depth-part-2.md)<br />** | ****| **开发常见方法介绍<br />** | ****| ** dispatch_after 延后工作<br />** | ****| ** Dispatch Groups 会在整个组的任务都完成时通知你<br />** | ****| **dispatch_semaphore_t 信号量,让你控制多个消费者对有限数量资源的访问。【[点击](http://www.tanhao.me/pieces/392.html/)】<br />** | ****| **dispatch_semaphore_wait 使得信号量-1,当=0时候阻塞<br />** | ****| **dispatch_semaphore_signal 释放信号量,即信号量+1<br />** | ****| **信号量也可以实现两个异步操作,都完成时(即相互等待)。再执行一些操作。<br />** | ****| **<br />** ****|**** ****|****-> ****CoreData**数据持久化,相比sqlite有下面优势【[点击](https://www.zhihu.com/question/20809133)】<br />** ****|**** ****| **数据库字段或者表有更改会导致crash,CoreData的版本管理和数据迁移变得非常有用,\<br />** ****|**** ****| **手动写sql语句操作还是麻烦一些。<br />** ****|**** ****| **不光能操纵SQLite,CoreData和iCloud的结合也很好,如果有这方面需求的话优先考虑<br />** ****|**** ****| **并不是直接操纵数据库,比如:使用CoreData时不能设置数据库的主键,目前仍需要手动操作。<br />** ****|**** ****| **效率上其实跑程序时感觉不出来,毕竟手机上的数据不能跟网站的数据和访问量相提并论。<br />** ****|**** ****/**<br />** ****|-> ****特殊封装&平台特性<br /> | ****\**** <br /> | |**->** 类别(Category)扩展(Extension)**微小区别【[点击】](http://blog.csdn.net/hherima/article/details/44242469)<br />** | | **堪称iOS编程的精髓【[点击](http://blog.csdn.net/hherima/article/details/44242469)[】念茜](http://blog.csdn.net/hherima/article/details/44242469)出品【[点击](http://blog.csdn.net/yiyaaixuexi/article/details/8970734)】<br />** ****|**** ****|->** **KVC** 键值编码<br />** ****|**** ****|** 在IOS的中,没有绝对的私有,包括方法和变量,可以通过字符获取属性【[点击】](http://blog.csdn.net/hherima/article/details/50675414)<br /> **|** ****|->**** **KVO** 键值观察,依赖isa-swizzling技术【王中周出品 [点击](http://blog.csdn.net/wzzvictory/article/details/9674431)】<br /> **|** **|** ** **依赖Runtime 和KVC 一个新的类会动态被创建。详细原理【[点击】](http://www.cocoachina.com/ios/20150313/11321.html)另外一篇【[点击】](http://www.tekuba.net/wap.asp?act=View&id=294)<br /> **|** **|** ** **同时派生类还重写了 class 方法以“欺骗”外部调用者它就是起初的那个类。<br /> **|** **|** ** **然后系统将这个对象的 isa 指针指向这个新诞生的派生类,因此这个对象就成为该派生类的对象了,<br /> **|** **|** ** **因而在该对象上对 setter 的调用就会调用重写的 setter,从而激活键值通知机制<br /> **|** **|** ** **★****Person在建立KVO监听前和之后的打印输出 self->isa:Person [self class]:Person <br />** | ****|**** **self->isa:NSKVONotifying_Person [self class]:Person <br /> **|** **|** ★比如:Tableview上拉下拉动画检测offset;播放视频,获取视频时长时候等<br /> **|** **|** 为什么KVO不成对儿调用,会崩溃?<br /> **|** **|->** **多任务<br /> | **|** **后台运行一段时间(不是地图,voip类app)【[点击](http://blog.csdn.net/hherima/article/details/50780931)】<br /> **|** **|->** **3D Touch** ,通过在plist中添加菜单,然后app实现下面的方法。进入APP<br /> **|** **| **- (void)application: performActionForShortcutItem: completionHandler:<br /> **|** **|->** **spotlight** 通过系统搜索,进入APP【[点击](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/AppContent.html#//apple_ref/doc/uid/TP40016308-CH7-SW1)】<br /> **|** **\****->** **Touch ID** 如何使用iOS 8 指纹识别,代码、实例【[点击](http://blog.csdn.net/hherima/article/details/32154769)】<br />** **|->** HTTPs <br /> ****| **建立安全链接<br /> **|** 之前做过一段IM,对基本建立安全链接略知一二**【**[点击](http://blog.csdn.net/hherima/article/details/30793267)**】**<br />** | HTTPS**进阶【[点击](http://oncenote.com/2014/10/21/Security-1-HTTPS/)】【[本人总结](http://blog.csdn.net/column/details/rsa-certificate.html)】<br />** **| ****一句话概括https的ssl加密过程:整个加密过程涉及:非对称加密和对称加密两种技术,其中非对称加密<br />** **|** **(由于RSA计算速度特别慢,无法对大量信息加密)用于简历安全链接,确保server和客户端<br />** **|** **的合法(这需要证书机制);对称加密,则基于刚刚的安全链接之上,对传输内容的加密(加密速度很快)<br />** **|** **整个过程需要4次握手<br />** ****|**<br /> **\->** **iOS工具**<br /> CrashHlytics Crash统计工具<br /> AFNetworking 和 ASIHttp<br /> SDImage<br /> TMCache<br /> AsyncDisplayKit 是 Facebook 推出的用于保持界面流畅性的框架<br />------------------------------------------------------------------------------------------<br /> 参考文献:《Objective-C高级编程:iOS与OS X多线程和内存管理》日本人写的;<br /> 《Effective Objective C 2.0:编写高质量iOS与OS X代码的52个有效方法》;<br /> 《Objective-C基础教程(第2版)》 <br />网络博客参考(无循序):念茜、南峰子、ibireme、容芳志、唐巧、王巍、董柏然、阮一峰、一片枫叶,王中周,颐和园等博主<br />参考的公众帐号:《iOSDevTips》即唐巧的公众帐号;《iOSDevTip》

完整的UIKit和Foundation 结构 [点击](http://www.cnblogs.com/kenshincui/p/3885689.html)