mac项目运行打包出来是app,ios运行打包出来是ipa
info.plist是全局配置文件,包含项目中所有的配置数据
项目中其他plist文件不能带有info字眼,否则容易被错认为是info.plist文件。只要改了info.plist,一般需要做两件事情,1,clean,2,卸载软件
/*****pch文件日志输出功能******/
#ifdef __OBJC__
#ifdef DEBUG
#define GXFLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define GXFLog(...)
#endif
#endif
/*********随机色***********/
#define GXFRandomColor [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0]
切换控制器方法:1.导航控制器,2.标签控制器,3.modal(控制器modal控制器)。modal
使用场合,如果是两个不想关的控制器,比如联系人列表点击右上角有添加联系人按钮,来到编辑联系人控制器,这时可以用modal;如果两个控制器之间有联系,比如设置,一层套一层,一般用push比较好
#pragma mark - 如果UITableViewController里面的tableView用的是静态单元格,一定要把系统自动生成的那些数据源方法删掉,因为代码优先级最高,优先看数据源方法
GCD:
串行队列(同步函数中的任务顺序执行,并且在当前线程;异步函数中的任务并发执行,并且只开一个线程。串行队列最多两个线程,主线程和一个子线程),并行队列(同步函数中的任务照样顺序执行,并且在当前线程;异步函数中的任务并发执行,执行顺序不能控制,并且不能确定线程数),全局并发队列(与手动创建的并发队列效果一样,参数永远用0和0),一般不会自己创建并发队列,主队列(只能有异步函数,有同步函数会发生阻塞)
串行队列异步函数是最安全的,开发中常用
Operation:和GCD的并行队列差不多(应该是可以换用的),所以开启的线程数也不能确定,并且没有顺序,需要设置依赖。依赖关系是可以跨队列的(Operation的自定义队列和main队列)。新建线程是有开销的,但是Operation可以控制最大的线程数量(不太准,会比这个数稍大一点,是因为如果前一个线程工作完成,但是还没有销毁,会新建线程)应用:网络开发中的下载工作,3G开3个子线程,WIFI开6个子线程,可以控制最大的线程数来实现
抢票案例,认识到开发中多线程是存在不安全性的,由于UIKit中的绝大多数类都不是线程安全的,所以更新UI相关的操作,都应该在主线程中执行
NSThread中的两个方法,里面的参数YES会阻塞线程,直到perform调用完毕,而NO不会阻塞线程,就相当于并行队列一样,你干你的,不影响我的执行。缺点:不能自动回收线程,如果并发数量多,会建立大量的子线程,使用NSThread不会自动添加autoreleasepool,主线程是有自动释放池的,GCD和NSOperation也会自动添加自动释放池,唯独NSThread不会,需要手动添加自动释放池来保证不会出现内存泄漏
同步任务最主要目的是,阻塞并行队列任务的执行,只有当前的同步任务执行完毕后,后续任务才能够执行(用户登录)
基本数据类型变量int,char,float,double是在栈区。所有alloc出来的对象都是在堆区。release释放,是通知系统把对象从堆中拿走
copy,是原模原样的赋值,比如字符串,不可变字符串copy出来新的,还是不可变的,mutableCopy,不管之前对象能不能修改,mutableCopy出来就是可变的了。最常用法,遇到临时变量是可变的,而成员变量是不可变的情况下,应该使用copy,会很安全。自定义的对象都是可变的(Person)
代码内部使用int,定义变量使用NSInteger
导入第三方框架,第一件事是先编译com + B
想要获得响应头信息,用HEAD请求,由于很小,一般是同步请求,因为异步的话,后面的代码就走了,不知道什么时候返回响应头信息。请求是可变请求,但是注意,HEAD请求是HTTP协议定义的方法
nil是一个空的对象,用于OC,NULL是一个空的值,用于C语言
两个*是地址,是C语言,错误信息,两个*就是NULL
同步请求下载文件,和block异步下载是一样的,内存会暴涨
一旦range信息设置成功,服务器返回的相应行中的状态码就会变成206
NSUrlConnection的代理方法需要运行循环的驱动,默认是在主线程的运行循环中。解决:在子线程创建网络连接(套一层子线程),设置代理对象,然后在开启子线程的运行循环
如果没有设置代理回调的执行队列,下载过程就在同一条线程执行;如果设置了代理回调的执行队列为非主队列,下载过程会在多条线程同时执行,效率更高
两个特殊的事件源,[self performSelector...afterDelay...];和NSUrlConnection的代理方法,都需要运行循环的驱动。特殊性:方法执行结束后,运行循环会自动关闭,但一定要注意先添加事件源,再开启运行循环
如果是简单的GET请求,就可以直接使用url,如果是POST请求,就不能使用url了,需要设置request的请求头
NSURLSession网络任务:上传网络任务,下载网络任务,普通网络任务。对于大部分网络任务,NSUrlSession都可以满足,除了监听下载进度(NSURLSessionDownloadDelegate,注意:一旦设置了代理,就不要添加block回调了,否则代理回调会失效。使用代理那么shared就不能用了,需要用sessionWith...)。NSURLSession默认都是异步的,没有同步方法NSURLConnection中所有的异步任务都可以用NSURLSession来替代,但是内存该暴涨还是会暴涨
NSURLSessionDataTask:普通网络任务,和NSURLConnection一样,没有什么区别
NSUrlSessionDownloadTask:下载网络任务,方法中有一个location的参数,block执行完毕就会删除下载好的文件,需要即时保存起来(移动或复制)
3种比较耗时的操作,下载过程,io操作(输入输出流),文件的解压缩(本质也是输入输出流)
静态库:Xcode6.3之前需要手动添加,6.3之后只要利用#import导入头文件,就会自动添加
动态库:IOS7.0以后,所有的动态库都以.tbd结尾,7.0之前,动态库以.dylib结尾。是白色的
苹果机制,退出应用到后台之后,过一会苹果会自动杀掉应用程序,NSURLSession可以设置后台下载,退出应用到后台之后还能继续下载
同步:不会开启线程,任务按顺序执行;异步:除了回到主队列,都会开启线程
上传一般使用POST请求,NSURLSession上传时,file默认就是PUT请求,服务器不支持
MD5指纹识别,只要有任何改动,MD5就会变化,可以防止盗版
密码明文只能出现在用户登录窗口,其他地方(服务器,本地,传输过程中)都必须是密文
SVN必须要掌握,以后开发多用SVN,GIT用的不多,但是很多优秀的IOS第三方框架都是用GIT
KVO监听对象属性的改变,addObserver,有监听就必须有释放,被监听者销毁(dealloc)时,需要移除监听者,很像通知
如果重写set方法的属性是copy,那么需要把新传进来的值做一次copy再赋值给下划线属性
懒加载,是为了用到的时候创建对象,不知道什么时候用到它,但是如果知道什么时候用到它,那么就完全可以在准确的位置来创建对象,这样也就相当于懒加载了(用到的时候创建)
NSURLConnectionDataDelegate:直接使用内存缓存(data)保存下载好的内容
边下载,边将文件写入沙盒.
NSOutputStream :数据/输入输出流管道,建立管道用来流入/流出数据.
NSOutputStream使用:
1.创建 NSOutputStream 对象.依赖于本地文件路径.如果文件路径下存在文件,那么直接流入文件;如果文件不存在,直接创建一个空文件.
2.打开/关闭管道.
问题: 和 NSFileHandle一样,多次下载会拼接到同一个文件下.下载后的文件会变大.
获取服务器文件信息.
HTTP协议规定的方法:
HEAD 方法: 只获取服务器响应头内容(响应行/响应头),不获取实体内容.
一般在发送 HEAD 请求的时候,需要使用"同步"请求.
NSFileManager获取本地文件信息.
断点续传
告诉服务器需要获得的数据内容,服务器就会返回想要的内容.
已经设置过的请求头:
告诉服务器本地软件环境: User-Agent
POST文件上传设置POST的数据格式和边界信息: Content-Type
告诉服务器本次请求获取的数据段: Range
Range格式: bytes=x-y
bytes=x-y 从 x 字节开始下载,下载y个字节
bytes=x- 从 x 字节开始下载,下载到文件末尾
bytes=-x 从 文件开始下载,下载 x 字节
一旦 Range 信息设置成功,服务器返回的响应行中的状态码就回变成206.
判断: 本地文件大小和 服务器文件大小.
<1>本地没有这个文件: 第一次下载,直接下载!
<2>本地文件大小 < 服务器文件大小 :断点续传.
<3>本地文件大小 = 服务器文件大小 :文件已经下载完毕,直接找到文件路径,打开文件.
<4>本地文件大小 > 服务器文件大小 :删除原来的文件,重新下载新文件.
新问题: 默认情况下,下载过程在主线程,会影响与用户交互.
问题: 将代理回调的执行线程设置为子线程(非主队列),所有的代理方法都会在不同的子线程执行.
但是: 执行 UI 操作的时候,依然会阻塞下载过程!
监听下载进度.
进度条是一段一段的跳转,不能正确显示下载进度.
创建网络是在主线程!
将代理方法都放在子线程,并且要保证代理回调有子线程的运行循环来驱动!
将创建网络连接设置代理的方法放在子线程.
设置代理方法的执行线程为非主队列,会开启多条线程执行下载方法.
如果不设置代理方的的执行线程,默认只会开启一条线程执行下载方法.
运行循环的开启需要"事件源"(UI操作/定时器)的驱动.
两个比较特殊的事件源:
1>延时执行: [self performSelector:@selector(test) withObject:nil afterDelay:2];
2> NSUrlConnection的代理回调.
特殊性: 一般运行循环开启之后,就相当于添加了一个死循环.如果不手动关闭,运行循环就回始终存在!
对于上述两个特殊的事件源,一旦事件执行结束之后,运行循环就会自动关闭.
添加运行循环注意: 一定要先有事件源,然后再开启运行循环!
开启运行循环的方法:
[[NSRunLoop currentRunLoop] run]; 不能手动关闭.
CFRunLoopRun(),可以手动关闭运行循环.
CFRunLoopStop(CFRunLoopGetCurrent());关闭运行循环.
注意: NSUrlSession默认都是异步的.没有同步请求.替代 NSUrlConnection中所有的异步请求.
在文件删除之前,移动文件到沙盒.
[[NSFileManager defaultManager] moveItemAtPath:location.path toPath:@"/Users/apple/Desktop/aaa.zip" error:NULL];
如果需要设置代理对象,那么不能使用系统提供的全局的网络会话,需要手动实例化网络会话.
全局并发队列 和 自己手动创建的并发队列在开启线程的问题上一模一样.
一般在开发中,不会自己手动创建并发队列(除非是自己写框架,需要使用阻塞式函数),使用全局并发队列来代替并发队列.
使用svn的方式:命令行,Xcode,verssions,cornerstone
Cornerstone中,merge表示合并代码
控制台区别Json和字典,看key值是否有"",有引号就是Json,没有引号就是字典,看是等号(字典)还是冒号(Json)
NSURL中只能识别英文,不能有汉字,如果有汉字需要进行百分号转译
httpfgNNSURL中只能识别英文,不能有汉字,如果有汉字需要进行百分号转译
http://192.168.34.200/svn/group02
ios6的view不包括状态栏,关于ios6和ios7的适配,设置约束时顶部尽量还是以top为参考,不要以view
数组字符串可以用桥接来实现c与oc之间的转化
系统自带的.framework是动态库,我们自己生成的.framework是静态库。注意我们自己的静态库尽量用release版本,因为它更轻量级
app做好之后,最好先运行一下release版本,这才是真正用户手机上的应用
开发中如果想做一个效果,可以首先从code4app或者github或者stackoverflow搜索一下看看有没有自己想要的效果代码
block本质是指向结构体的指针
分类只可以扩充方法,但是如果使用运行时,也可以扩充属性
iPhone项目可以运行在iPad,但是ipad项目不能运行在iPhone。
navigationBar只能放左边和右边,toolBar可以放任何位置
view的frame一旦发生改变,就会调用layoutSubviews,这里拿到的是最真实的frame,initWithFrame添加子控件,layoutSubviews设置frame
SQLite3数据库是关系型数据库,不是对象型数据库。Core Data是苹果自带的,可以轻松操纵SQLite3而不用使用sql语句
xCode 4.5之前,定义了成员变量,不会自动生成带下划线的成员变量,需要手动使用@synchronized a = _a指令来生成带下划线的成员变量,但是只是本类,子类是没有带下划线成员变量的,想使用父类的属性,只能用self.a 所以4.5之后,如果子类想重写父类属性的getter方法,在方法内部self.a不可用,会造成死循环,所以只能使用@synchronized指令来让自己也拥有父类的带下划线的成员变量
程序是运行在内存中的,不能杀掉一个线程,但是可以暂停休眠一段时间
com+s com+shift+4截图代码
tableView的样式有两种group和plain,如果有多组,plain样式的组标题会停留在屏幕上方;tableViewcell有4种样式,default(只有图片和标题),subtitle(还有子标题), value1,value2,
自定义cell有3种方式,xib,纯代码,storyBoard每个cell长得一样可以用xib或storyBoard,内容不一样,高度也不一样,这时候用纯代码
cell高度不一样,就需要自定义cell,需要把最多的cell的控件全部创建,给自定义的cell设置一个模型属性,重写模型的setter方法,在setter方法中设置数据和设置frame([self setData], [self setFrame])计算一段文字占据的宽高,可以用[str boundingRect...]或者[str size...];
当mainBundle当做参数时,可以传入nil,默认就是mainBundle