iOS 总结

iOS是由苹果公司开发的移动操做系统.数据库

iOS 简介

开发语言

Object-C

  • 一般写做ObjC或OC和较少用的Objective C或Obj-C,是扩充C的面向对象编程语言。OC 彻底兼容 C语言.
  • 面向对象语言(C 语言面向过程).
  • 是MAC OSX和IOS开发的基础语言。

Swift

  • 苹果于2014年WWDC(苹果开发者大会)发布的新开发语言,可与Objective-C*共同运行于Mac OS和iOS平台,用于搭建基于苹果平台的应用程序.
  • Swift和Objective-C共用一套运行时环境,项目中能够经过桥接的方式互相调用.

开发工具

  • Xcode: 运行在操做系统Mac OS X上的集成开发工具(IDE),由苹果公司开发。

iOS 基础

APP 生命周期

iOS 应用有5中状态:编程

  • Not running 应用还没启动或正在运行可是中途被系统中止
  • Inactive 应用正在前台运行(不接收事件)
  • Active 应用正在前台运行(接收事件)
  • Background 应用处于后台运行(还在执行代码)
  • Suspended 应用处于后台运行(中止执行代码) 对应的函数:
//应用将要进入非活动调用 (不接受消息或事件)
- (void)applicationWillResignActive:(UIApplication *)application;
//应用进入活动调用 (接收消息或事件)
- (void)applicationDidBecomeActive:(UIApplication *)application;
//应用进入后台调用 (设置后台继续运行)
- (void)applicationDidEnterBackground:(UIApplication *)application;
//应用将要进入前台调用
- (void)applicationWillEnterForeground:(UIApplication *)application;
//应用将要退出调用 (保存数据,退出前清理)
- (void)applicationWillTerminate:(UIApplication *)application;
//应用被终止前调用 (内存清理,方式应用被终止)
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;
//应用载入后调用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
//应用打开URL时调用
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
复制代码

内存管理机制(引用计数)

简介

OC 引入引用计数机制来跟踪并管理对象的生命周期. iOS 5以前采用 MRC(手动内存管理) 管理内存.需用开发人员手动调用reatain,release等方法.
iOS 5以后采用 ARC(自动内存管理) 管理内存,不用开发人员去关心引用计数的变化.swift

操做 对应 OC 方法 引用计数变化
建立对象 alloc,new 等 生成对象,引用计数设置为 1
持有对象 reatain 引用计数 +1
释放对象 release 引用计数 -1
废弃对象 dealloc 引用计数为0,释放内存

alloc 与 dealloc,reatain与 release 成对存在, 谁建立谁释放,谁retain谁释放
只有当引用计数为 0 是对象才会销毁回收内存.设计模式

工做原理

  • 当咱们建立(alloc)一个新对象A的时候,它的引用计数从零变为 1.
  • 当有一个指针指向这个对象A,也就是某对象想经过引用保留(retain)该对象A时,引用计数加 1.
  • 当某个指针/对象再也不指向这个对象A,也就是释放(release)该引用后,咱们将其引用计数减 1.
  • 当对象A的引用计数变为 0 时,说明这个对象再也不被任何指针指向(引用)了,这个时候咱们就能够将对象A销毁,所占内存将被回收,且全部指向该对象的引用也都变得无效了。系统也会将其占用的内存标记为“可重用”(reuse).

属性

声明

@property(nonatomic, strong)UITextField *textField;
OC 采用 '@property' 声明对象, 会默认生成一个 '_textField' 成员变量与与之对应的 'setter/getter' 方法.缓存

属性修饰符

修饰符 描述 引用计数变化
copy 复制,建立一个新对象,一般修饰 NSString,NSArray,NSDictionary,NSSet 新对象引用计数为 1,旧对象不变
retain 释放旧对象,主要用于(MRC) 释放旧对象,计数 -1,新对象 retain, 计数 +1
strong 强引用,与 retain类似 释放旧对象,计数 -1,新对象 retain, 计数 +1
assign 修饰基本数据类型 不变
weak 与assign相似,修饰对象,对消销毁后自动变成 nil,主要用于修饰 delegate 不变
readwrite 可读写,生成 setter 与 getter 方法 -
readonly 只读,只为属性生成 getter 方法 -
nonatomic 非原子属性,不为 setter 方式加锁,非线程安全,一般采用这种,执行效率高 -
atomic 原子属性,为 setter 方式加锁,线程安全 -

注意问题

  • 对 block 修饰 Strong,copy 均可以,建议使用 copy. block 声明默认为栈变量,为了可以在block的声明域外使用,因此要把block拷贝(copy)到堆,因此说为了block属性声明和实际的操做一致,最好声明为copy。
  • NSString,NSArray,NSDictionary,NSSet 建议使用 copy. 当将 NSMutableString 赋值给 NSString 时, strong 修饰只会进行浅拷贝(引用计数 +1),NSMutableString与NSString 指向同一内存空间,NSMutableString修改时NSString会随之改变. copy 修饰深拷贝(复制内存单元),NSMutableString与NSString 指向不一样内存空间,NSMutableString修改时NSString不会改变.
  • __weak __Strong __block 在 block 使用时有时为了不形成循环引用会用 __weak __Strong 进行修饰下. 有时在 block 中,为了不对象过早释放用 __Strong 修饰.

数据持久化

  • 读写文件: 比较复杂,对对象保存须要进行归档反归档处理.
  • 云端存储: 须要后台配合.
  • 本地数据库(SQLite,CoreDate): CoreDate 是 iOS5 以后出现的,实质是对 SQLite 的封装.
  • NSUserDefaults: 系统自带的持久化类,进行简单数据存储(用户登陆信息等).

类继承关系(单继承)

iOS 全部的类都继承与 NSObject, 主要分为 UI 和 NS 两大类. UI 主要为视图, NS 为数据操做. 图解: ![UI 系](iOS 总结_1.png) ![UI 系](iOS 总结_2.png)安全

其余: UIViewController 生命周期: 初始化 --> loadView --> viewDidLoad --> viewWillAppear --> viewWillLayoutSubviews --> viewDidLayoutSubviews --> viewDidAppear --> viewWillDisappear --> viewDidDisappear --> deallocapp

传值

  • 属性传值
  • block 传值
  • 代理传值
  • 通知传值
  • 单例传值
  • 持久化传值

协议与代理

在iOS开发中,Protocol是一种常常用到的设计模式,苹果的系统框架中也广泛用到了这种方式,好比UITableView中的. 协议声明:框架

#import <Foundation/Foundation.h>

@protocol ProtocolDelegate <NSObject> // 必须实现方法 @required - (NSString*)getName; // 可选方法 @optional - (NSString*)getAge; @end 复制代码

协议使用异步

  • 协议是一系列标准的方法列表,能够被任何类实现.
  • 协议中不能声明成员变量,只要一个类遵照了这个协议,也至关于拥有了该协议中全部方法的声明.
  • 父类遵照了该协议,那么它的子类也就都遵照该协议,能够遵照多个协议.

代理: 当前类(委托者)将一些操做委托给另外一个类(代理)去完成. 委托者须要作的事:编程语言

  • 建立协议(也就是代理要实现的方法)
  • 声明委托变量
  • 设置代理(也能够在代理中设置)
  • 利用委托变量来调用协议方法(也就是让代理者开始执行协议) 代理须要作的事:
  • 遵循协议
  • 实现协议方法

数据请求

iOS 中级

响应者链

  • 响应对象: 继承自UIResponder的对象称之为响应者对象.
  • 响应事件: 触摸事件、点按事件(长按,屡次点击,轻点等)、加速事件和远程控制.
  • 响应者链: 由多个响应者组合起来的链条

事件产生与传递

  • 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中.
  • UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,一般,先发送事件给应用程序的主窗口(keyWindow).
  • 主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件,这也是整个事件处理过程的第一步.
  • 找到合适的视图控件后,就会调用视图控件的touches方法来做具体的事件处理.
  • 若是调用了[super touches….];就会将事件顺着响应者链条往上传递,传递给上一个响应者,调用上一个响应者的touches….方法 注意: 若是父控件不能接受触摸事件,那么子控件就不可能接收到触摸事件 ![UI 系](iOS 总结_3.png)

事件响应

  • 若是视图不响应事件,则将其传递给它的父视图
  • 在最顶级的视图层次结构中,若是都不能处理收到的事件或消息,则其将事件或消息传递给UIWindow对象进行处理
  • 若是UIWindow对象也不处理,则其将事件或消息传递给UIApplication对象处理
  • 若是UIApplication也不能处理该事件或消息,则将该事件丢弃 如何判断上一个响应者
    • 若是当前这个view不是控制器的view, 那么它的父控件就是上一个响应者
    • 若是当前这个view是控制器的view, 那么控制器就是上一个响应者

UIView不能接收触摸事件的状况

  • 不容许交互: userInteractionEnabled = NO(eg: UIImageView)
  • 隐藏
  • 透明度: 透明度<0.01
  • 子视图超出了父视图区域
  • 当前 View 被遮挡

分类(category)与类扩展(extension)

分类

  • 在不改变原类的基础上为一个类扩展方法.
  • 主要用法为系统类扩展方法
  • 不可添加成员变量. 若是要添加成员变量须要本身实现 setter 和 getter 方法(runtime).
  • 分类文件(.h,.m),觉得 Person 添加分类为例,能够经过 Person 实例对象直接调用 playFootBall 方法(分类方法执行优先级高于本类).

Person+sport.h

#import "Person.h"

@interface Person (sport)

- (void)playFootBall;

@end

复制代码

Person+sport.m

#import "Person+sport.h"

@implementation Person (sport)

- (void)playFootBall {
    NSLog(@"playFootBall");
}

@end

复制代码

类扩展

类扩展是分类的一个特例,为一个类添加一些私有成员变量和方法(经常使用). 类扩展定义的方法,须在类的implement 中实现 类扩展能够定义属性 声明:

#import "Person.h"

@interface Person ()
- (void)say;
@end
复制代码

分类与继承

iOS 中分类(Categories) 和 继承(Inherit)有相同的功能,但在一些细节上又有差别,如何选择。 使用继承:

  • 扩展方法与原方法名相同,还须要使用父类方法.
  • 扩展类属性(分类不能扩展类属性) 使用分类:
  • 为系统类添加方法(eg: 为 NSString 添加字符串校验).
  • 开发人员针对本身的类,将相关方法分组到不一样的文件.

UITableView 重用机制

UITableView 是 iOS 开发中最长用的控件,为了节省内存开销, UITableView 使用重用机制(重用 cell 单元格).

使用重用机制建立 cell

  • 定义重用标示(static 修饰字符串).
  • 在重用池取出 cell.
  • 若重用池没有可用 cell, 建立新的 cell.
static NSString *reuseIndentifier = @"MyCell";  
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIndentifier];  
if (!cell) {  
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIndentifier];  
}
复制代码

原理

UITableView 维护这两个队列,单前可视 cell 队列 visiableCells, 可重用 cell 队列 reusableTableCells(重回池). 在最初visiableCells, reusableTableCells 都为空, "UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];" 获取 cell 为 nil, 执行 cell 初始化方法建立显示并存入到 visiableCells.若是屏幕最多显示 cell 个数为10,当加载完第11个 cell 时建立的第一个 cell 在 visiableCells 移除加入到 reusableTableCells 中,因此在加载第12个 cell 时只需在 reusableTableCells 取出 cell 便可.第十二个 cell 加载完成后建立的第二个 cell 移出 visiableCells 进入 reusableTableCells 中,依次类推(理论讲只需建立11个 cell 就可).

遇到问题和优化

  • 重取出来的cell是有可能已经捆绑过数据或者加过子视图的,形成视图叠加混乱的现象
    • 删除已有数据或子视图.
    • 放弃了重用机制,每次根据indexPath获取对应的cell返回(内存销耗特大).
  • 结合 MJFresh 实现数据分页加载.
  • 结合 SDWebImage 实现 cell 中图片异步加载以及缓存.
相关文章
相关标签/搜索