[TOC]html
1. 首先搞清楚什么是线程、什么是多线程 2. Mach是第一个以多线程方式处理任务的系统,所以多线程的底层实现机制是基于Mach的线程 3. 开发中不多用Mach级的线程,由于Mach级的线程没有提供多线程的基本特征,线程之间是独立的 4. 开发中实现多线程的方案 C语言的POSIX接口:#include <pthread.h> OC的NSThread C语言的GCD接口(性能最好,代码更精简) OC的NSOperation和NSOperationQueue(基于GCD)
1. performSelector:onThread:withObject:waitUntilDone: 2. NSMachPort
利用字典(图片地址为key,下载操做为value),具体能够查看SD缓存机制
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSOperation *A = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"SuperLog------ NSOperationA"); }]; NSOperation *B = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"SuperLog------ NSOperationB"); }]; NSOperation *C = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"SuperLog------ NSOperationC"); }]; [C addDependency:A]; [C addDependency:B]; [queue addOperation:A]; [queue addOperation:B]; [queue addOperation:C];
1. 只在主线程刷新访问UI 2. 若是要防止资源抢夺,得用synchronized进行加锁保护 3. 若是异步操做要保证线程安全等问题, 尽可能使用GCD(有些函数默认就是安全的)
1. iOS和OS X的核心是XNU内核,GCD是基于XNU内核实现的 2. GCD的API所有在libdispatch库中 3. GCD的底层实现主要有Dispatch Queue和Dispatch Source Dispatch Queue :管理block(操做) Dispatch Source :处理事件
1. GCD是纯C语言的API,NSOperationQueue是基于GCD的OC版本封装 2. GCD只支持FIFO的队列,NSOperationQueue能够很方便地调整执行顺序、设置最大并发数量 3. NSOperationQueue能够在轻松在Operation间设置依赖关系,而GCD须要写不少的代码才能实现 4. NSOperationQueue支持KVO,能够监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld) 5. GCD的执行速度比NSOperationQueue快 任务之间不太互相依赖:GCD 任务之间有依赖\或者要监放任务的执行状况:NSOperationQueue
Block的使用注意: 1. block的内存管理 2. 防止循环retian 非ARC(MRC):__block ARC:__weak\__unsafe_unretained
1. 从新下载图片 2. 下载完毕, 利用RunLoop的输入源回到主线程刷新UIImageView
1. 使用Analyze进行代码的静态分析 2. 尽可能使用ARC
建立单例设计模式的基本步骤: 1. 声明一个单件对象的静态实例,并初始化为nil 2. 建立一个类的类工厂方法,当且仅当这个类的实例为nil时生成一个该类的实例 3. 实现NScopying协议, 覆盖allocWithZone:方法,确保用户在直接分配和初始化对象时,不会产生另外一个对象 4. 覆盖release、autorelease、retain、retainCount方法, 以此确保单例的状态。 5. 在多线程的环境中,注意使用@synchronized关键字或GCD,确保静态实例被正确的建立和初始化。
1. 系统自带的绝大数类方法返回的对象,都是通过autorelease的
1. 对于没有引用外部变量的Block,不管在ARC仍是非ARC下,类型都是__NSGlobalBlock__,这种类型的block能够理解成一种全局的block,不须要考虑做用域问题。同时,对他进行Copy或者Retain操做也是无效的 2. 应注意避免循环引用
1. 当程序在申请内存后,没法释放已申请的内存空间(例如一个对象或者变量使用完成后没有释放,这个对象一直占用着内存),一次内存泄露危害能够忽略,但内存泄露堆积后果很严重,不管多少内存,早晚会被占光。内存泄露会最终会致使内存溢出! 2. 当程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;好比申请了一个int,但给它存了long才能存下的数,那就是内存溢出。
[NSArray arrayWithobject:(id)obj]
这个方法添加对象后,须要对这个数组作释放操做吗?不须要这个对象被放到自动释放池中
自动释放池以栈的形式实现:当你建立一个新的自动释放池时,它将被添加到栈顶。当一个对象收到发送autorelease消息时,它被添加到当前线程的处于栈顶的自动释放池中,当自动释放池被回收时,它们从栈中被删除, 而且会给池子里面全部的对象都会作一次release操做.
1. KVO是基于runtime机制实现的 2. 当某个类的对象第一次被观察时,系统就会在运行期动态地建立该类的一个派生类,在这个派生类中重写基类中任何被观察属性的setter方法。 3. 派生类在被重写的 setter 方法实现真正的通知机制(NSKVONotifying_Class)
若是在异步线程发的通知,那么能够执行比较耗时的操做 若是在主线程发的通知,那么就不能够执行比较耗时的操做
1. Foundation对象是OC的,Core Foundation对象是C对象 2. 数据类型之间的转换 ARC:__bridge_retained、__bridge_transfer 非ARC: __bridge
A = A + B B = A - B A = A - B A = A^B; B = A^B; A = A^B;
节省内存资源,一个应用就一个对象。
运行时机制,runtime库里面包含了跟类、成员变量、方法相关的API,好比获取类里面的全部成员变量,为类动态添加成员变量,动态改变类的方法实现,为类动态添加新的方法等 须要导入<objc/message.h> <objc/runtime.h> 1. runtime,运行时机制,它是一套C语言库 2. 实际上咱们编写的全部OC代码,最终都是转成了runtime库的东西,好比类转成了runtime库里面的结构体等数据类型,方法转成了runtime库里面的C语言函数,平时调方法都是转成了objc_msgSend函数(因此说OC有个消息发送机制)。所以,能够说runtime是OC的底层实现,是OC的幕后执行者 3. 有了runtime库,能作什么事情呢?runtime库里面包含了跟类、成员变量、方法相关的API,好比获取类里面的全部成员变量,为类动态添加成员变量,动态改变类的方法实现,为类动态添加新的方法等。所以,有了runtime,想怎么改就怎么改
CoreText 1. 随意修改文本的样式 2. 图文混排(纯C语言) 3. 国外:Niumb Core Image(滤镜处理) - 能调节图片的各类属性(对比度, 色温, 色差等)
通知比较灵活(1个通知能被多个对象接收, 1个对象能接收多个通知) 代理比较规范,可是代码多(默认是1对1) KVO性能很差(底层会动态产生新的类),只能监听某个对象属性的改变, 不推荐使用(1个对象的属性能被多个对象监听,1个对象能监听多个对象的其余属性)
更详细参考:java
原文ios
翻译web
Objective-C是对C语言的扩展,block的实现是基于指针和函数指针
算法题,百度本身学习。 思路 1. 计算 differ = sum(a) - sum(b) 2. 寻找 a b 数组中差值最接近differ/2 的元素 3. 交换元素
编写SQL语句来操做原来表中的字段 1. 增长表字段 ALTER TABLE 表名 ADD COLUMN 字段名 字段类型; 2. 删除表字段 ALTER TABLE 表名 DROP COLUMN 字段名; 3. 修改表字段 ALTER TABLE 表名 RENAME COLUMN 旧字段名 TO 新字段名;
1. 添加SQLite动态库 2. 导入主头文件:#import <sqlite3.h> 3. 利用C语言函数建立/打开数据库,编写SQL语句
1. 缓存能够分为:内存数据缓存、数据库缓存、文件缓存 2. 每次想获取数据的时候 2.1 先检测内存中有无缓存 2.2 再检测本地有无缓存(数据库\文件) 2.3 最终发送网络请求 2.4 将服务器返回的网络数据进行缓存(内存、数据库、文件),以便下次读取
1. CoreData是对SQLite数据库的封装 2. CoreData中的NSManagedObjectContext在多线程中不安全 3. 若是想要多线程访问CoreData的话,最好的方法是一个线程一个NSManagedObjectContext 4. 每一个NSManagedObjectContext对象实例均可以使用同一个NSPersistentStoreCoordinator实例,这是由于NSManagedObjectContext会在便用NSPersistentStoreCoordinator前上锁
ios中不存在缓存池满的状况,由于一般咱们ios中开发,对象都是在须要的时候才会建立,有种经常使用的说话叫作懒加载,还有在UITableView中通常只会建立刚开始出如今屏幕中的cell,以后都是从缓存池里取,不会在建立新对象。缓存池里最多也就一两个对象,缓存池满的这种状况通常在开发java中比较常见,java中通常把最近最少使用的对象先释放。
Core Animation Programming Guideobjective-c
// cnblog mermaid 使用后,[TOC] 目录失效,因此暂时放上源码和一张截图。 graph TB A(CAAnimation) --> B1(CAPropertyAnimation) A --> B2(CAAnimationGroup) A --> B3(CATransition) B1 --> C1(CABasicAnimation) B1 --> C2(CAKeyframeAnimation) C1 --> D(CASpringAnimation)
如何找到最合适的视图 1. 本身是否能接收触摸事件 2. 触摸点是否在本身身上 3. 从后往前遍历子控件,重复前面的两个步骤 4. 若是没有符合条件的子控件,那么本身最适合处理
1. 首先判断控制器是否有视图,若是没有就调用loadView方法建立(storyboard/代码) 2. 随后调用viewDidLoad,能够进行下一步的初始化操做(只会被调用一次) 3. 在视图显示以前调用viewWillAppear(该函数能够屡次调用) 4. viewDidAppear 3. 在视图显示以前调用viewWillDisappear;该函数能够屡次调用(如须要) 5. 在布局变化先后,调用viewWill/DidLayoutSubviews处理相关信息
NSRunLoop是iOS消息机制的处理模式 1. NSRunLoop的主要做用:控制NSRunLoop里面线程的执行和休眠,在有事情作的时候使当前NSRunLoop控制的线程工做,没有事情作让当前NSRunLoop的控制的线程休眠。 2. NSRunLoop 就是一直在循环检测,从线程start到线程end,检测inputsource(如点击,双击等操做)异步事件,检测timesource同步事件,检测到输入源会执行处理函数,首先会产生通知,corefunction向线程添加runloop observers来监听事件,意在监听事件发生时来作处理。 3. runloopmode是一个集合,包括监听:事件源,定时器,以及需通知的runloop observers 多线程中如何使用? 1. 只有在为你的程序建立次线程的时候,才须要运行run loop。对于程序的主线程而言,run loop是关键部分。Cocoa提供了运行主线程run loop的代码同时也会自动运行run loop。iOS程序UIApplication中的run方法在程序正常启动的时候就会启动run loop。若是你使用xcode提供的模板建立的程序,那你永远不须要本身去启动run loop 2. 在多线程中,你须要判断是否须要run loop。若是须要run loop,那么你要负责配置run loop并启动。你不须要在任何状况下都去启动run loop。好比,你使用线程去处理一个预先定义好的耗时极长的任务时,你就能够毋需启动run loop。Run loop只在你要和线程有交互时才须要
通常的应用在进入后台的时候能够获取必定时间来运行相关任务,也就是说能够在后台运行一小段时间(10S左右)。 1. 后台播放音乐 2. 后台GPS跟踪 3. 后台voip支持
程序启动分为两类: 1. 有storyboard 2. 没有storyboard 状况一: 1.main函数 2.UIApplicationMain * 建立UIApplication对象 * 建立UIApplication的delegate对象 3.根据Info.plist得到最主要storyboard的文件名,加载最主要的storyboard(有storyboard) * 建立UIWindow * 建立和设置UIWindow的rootViewController * 显示窗口 状况二: 1.main函数 2.UIApplicationMain * 建立UIApplication对象 * 建立UIApplication的delegate对象 3.delegate对象开始处理(监听)系统事件(没有storyboard) * 程序启动完毕的时候, 就会调用代理的application:didFinishLaunchingWithOptions:方法 * 在application:didFinishLaunchingWithOptions:中建立UIWindow * 建立和设置UIWindow的rootViewController * 显示窗口
1. 关掉后不执行任何代码,不能处理事件 2. 应用程序进入后台状态不久后转入挂起状态。在这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除。只有当用户再次运行此应用,应用才会从挂起状态唤醒,代码得以继续执行 3. 或者进入后台时开启多任务状态,保留在内存中,这样就能够执行系统容许的动做 4. 远程推送是由远程服务器上的程序发送到APNS,再由APNS把消息推送至设备上的程序,当应用程序收到推送的消息会自动调用特定的方法执行事先写好的代码 5. 本地通知和远程推送通知对基本概念和用法? * 本地通知和远程推送通知均可以向不在前台运行的应用发送消息,这种消息既多是即将发生的事件,也多是服务器的新数据.不论是本地通知仍是远程通知,他们在程序界面的显示效果相同,均可能显示为一段警告信息或应用程序图标上的微章. * 本地通知和远程推送通知的基本目的都是让应用程序可以通知用户某些事情,并且不须要应用程序在前台运行.两者的区别在于本地通知由本应用负责调用,只能从当前设备上的iOS发出, 而远程通知由远程服务器上的程序发送到APNS,再由APNS把消息推送至设备上的程序
1. SIP(Session Initiation Protocol),会话发起协议 2. SIP是创建VOIP链接的 IETF 标准,IETF是全球互联网最具权威的技术标准化组织 3. 所谓VOIP,就是网络电话,直接用互联网打电话,不用耗手机话费
1. 图片下载放在异步线程 2. 图片下载过程当中使用占位图片 3. 若是图片较大,能够考虑多线程断点下载
1. 提供给外界的接口功能是否实用、够用 2. 能不能根据类名、方法名就猜出接口的具体做用 3. 提供的参数是否够用、调用起来是否简单 4. 要不要再导入依赖其余的框架
1. 设置请求超时 2. 给用户提示请求超时 3. 根据用户操做再次请求数据
1. 若是通知是在主线程发出,那么接收通知的方法中的耗时操做要放到异步线程中 2. 若是通知实在异步线程中发出,那么接收通知后调用的方法会默认在异步线程中执行
1. 利用NSOperationQueue和NSOperation下载图片, 还使用了GCD的一些函数(解码GIF图片) 2. 利用URL做为key,NSOperation做为value 3. 利用URL做为key,UIImage做为value 待完善...
1. AFN基于NSURL,ASI基于底层的CFNetwork框架,所以ASI的性能优于AFN 2. AFN采起block的方式处理请求,ASI最初采起delegate的方式处理请求,后面也增长了block的方式 3. AFN只封装了一些经常使用功能,知足基本需求,直接忽略了不少扩展功能,好比没有封装同步请求;ASI提供的功能较多,预留了各类接口和工具供开发者自行扩展 4. AFN直接解析服务器返回的JSON、XML等数据,而ASI比较原始,返回的是NSData二进制数据
1. 你建立的程序不须要显示的建立run loop;每一个线程,包括程序的主线程(main thread)都有与之相应的run loop对象, 主线程会自行建立并运行run loop 2. Runloop处理的输入事件有两种不一样的来源:输入源(input source)和定时源(timer source) 3. 输入源传递异步消息,一般来自于其余线程或者程序。定时源则传递同步消息,在特定时间或者必定的时间间隔发生
1. 检查网络请求操做是否被放在主线程了 2. 看看异步请求的数量是否太多了(子线程数量) 3. 数据量是否太大?若是太大,先清除一些没必要要的对象(看不见的数据、图片) 4. 手机CPU使用率和内存问题
1. 设置数据库锁定的处理函数 int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); 2. 设定锁定时的等待时间 int sqlite3_busy_timeout(sqlite3*, 60);