Marks

iOS开发者,喜欢研究技术。

0%

KVO

KVO,即key-value-observing,利用一个key来找到某个属性并监听其值得改变。其实这也是一种典型的观察者模式。
简单的说,kvo的用法非常简单。

  1. 添加观察者
  2. 在观察者中实现监听方法,observeValueForKeyPath: ofObject: change: context:(通过查阅文档可以知道,绝大多数对象都有这个方法,因为这个方法属于NSObject)
  3. 移除观察者

如果将一个对象设定成属性,这个属性是自动支持KVO的,如果这个对象是一个实例变量,那么,这个KVO是需要我们自己来实现的.

阅读全文 »

可选型optional ,表示一个值可能为空。但是这个空,在swift中就叫可选型,用关键字nil表示。它既不是0,也不是不存在,它就是nil

要么是它自身的值,要么为nilnil就是可选型的默认值

阅读全文 »

前言

Swift type System

图片

Swift是强类型的,尽管只有六种类型。

  • 命名类型: protocol, class , struct , enum
  • 复合类型:tuple, function

可能会有疑问,那些基本类型:Bool,Int,UInt, Float, Double, Character, String, Array, Set, Dictionary, Optional。实际上他们都是通过命名类型创建的。

Struct Class and Enum 对比

copy by inheritance static variable instance variable static method instance method
Class Reference
Struct Value
Enum Value

枚举、结构体、类的共同点:

  • 定义属性和方法;
  • 下标语法访问值;
  • 初始化器;
  • 支持扩展增加功能;
  • 可以遵循协议;
  • 都可以使用泛型;

类特有的功能:

  • 继承;
  • 允许类型转换;
  • 析构方法释放资源;
  • 引用计数;
阅读全文 »

布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

2009年,W3C提出了一种新的方案—-Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。

Flex布局将成为未来布局的首选方案。

阅读全文 »

一、URL Session的基本概念

1. 三种工作模式:

  • 默认会话模式(default):工作模式类似于原来的NSURLConnection,使用的是基于磁盘缓存的持久化策略,使用用户keychain中保存的证书进行认证授权。
  • 瞬时会话模式(ephemeral):该模式不使用磁盘保存任何数据。所有和会话相关的caches,证书,cookies等都被保存在RAM中,因此当程序使会话无效,这些缓存的数据就会被自动清空。
  • 后台会话模式(background):该模式在后台完成上传和下载,在创建Configuration对象的时候需要提供一个NSString类型的ID用于标识完成工作的后台会话。

2. NSURLSession支持的四种任务

NSURLSession类支持四种类型的任务:加载数据,下载和上传,建立一个TCP/IP连接。

二、相关的类

1. NSURLConnection和NSURLSession

NSURLConnection这个名字,实际上指的是一组构成Foundation框架中URL加载系统的相互关联的组件:NSURLRequest,NSURLResponse,NSURLProtocol,NSURLCache,NSHTTPCookieStorage,NSURLCredentialStorage,以及和它同名的NSURLConnection。
在WWDC 2013中,Apple的团队对NSURLConnection进行了重构,并推出了NSURLSession作为替代。
NSURLSession也是一组相互依赖的类,它的大部分组件和NSURLConnection中的组件相同如NSURLRequest,NSURLCache等。而NSURLSession的不同之处在于,它将NSURLConnection替换为NSURLSession和NSURLSessionConfiguration,以及4个NSURLSessionTask的子类:NSURLSessionDataTask, NSURLSessionUploadTask, NSURLSessionDownloadTask,NSURLSessionStreamTask。

iOS为了适应不同的应用场景提供了不同类型的NSURLSessionTask

  • NSURLSessionTask : Task的抽象基类
  • NSURLSessionDataTask //一般的get、post等请求
  • NSURLSessionUploadTask // 用于上传文件或者数据量比较大的请求
  • NSURLSessionDownloadTask //用于下载文件或者数据量比较大的请求
  • NSURLSessionStreamTask //建立一个TCP/IP连接的主机名和端口或一个网络服务对象。可以执行一个异步的读写

2. NSURLSessionConfiguration

NSURLConnection是全局性的,即它的配置对全局有效,如果有两个链接需要不同的cookies、证书这些公共资源,则NSURLConnection无法满足要求,这时NSURLSession的优势则体现出来,NSURLSession可以同过NSURLSessionConfiguration可以设置全局的网络访问属性。

1
2
3
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
// delegateQueue:请求完成回调函数和代理函数的运行线程,如果为nil则系统自动创建一个串行队列,不影响sessionTask的运行线程
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];

三种会话方式:

  1. defaultSessionConfiguration:进程内会话(默认会话),类似 NSURLConnection的标准配置,用硬盘来缓存数据。
  2. ephemeralSessionConfiguration:临时的进程内会话(内存),不会将cookie、缓存储存到本地,只会放到内存中,当应用程序退出后数据也会消失,可以用于实现“秘密浏览”。
  3. backgroundSessionConfiguration:建立后台会话可以在应用程序挂起,退出,崩溃的情况下运行上传和下载任务,后台另起一个线程。另外,系统会根据设备的负载程度决定分配下载的资源,因此有可能会很慢甚至超时失败。

设置一些网络属性:

  • HTTPAdditionalHeaders:可以设置出站请求的数据头
1
2
3
4
5
6
configuration.HTTPAdditionalHeaders = @{ 
@"Accept": @"application/json",
@"Accept-Language": @"en",
@"Authorization": authString,
@"User-Agent": userAgentString
};
  • networkServiceType,设置网络服务类型
    • NSURLNetworkServiceTypeDefault 默认
    • NSURLNetworkServiceTypeVoIP VoIP
    • NSURLNetworkServiceTypeVideo 视频
    • NSURLNetworkServiceTypeBackground 后台
    • NSURLNetworkServiceTypeVoice 语音
    • NSURLNetworkServiceTypeCallSignaling 电话
  • allowsCellularAccess:允许蜂窝访问
  • timeoutIntervalForRequest:请求的超时时长
  • timeoutIntervalForResource:响应的超时时长
  • requestCachePolicy:缓存策略

注意事项:如果是自定义会话并指定了代理,会话会对代理进行强引用,在视图控制器销毁之前,需要取消网络会话,否则会造成内存泄漏

Objective-C中的BOOL类型在Watch和64位iOS上的原始类型为bool,而在其它情况下是signed char。我们用@encode去看看BOOL的类型串:

1
2
3
@encode(BOOL)		// 64位iOS系统:"B"
@encode(BOOL) // 32位iOS系统,32/64位OS X:"c"

所有这边有一个问题,下面这段代码中变量b的值在不同环境下,其结果可能是不一样的:

1
2
BOOL a = 100 & 20;
BOOL b = (a == YES);

当BOOL为bool时,b的值为1;而当BOOL为signed char时,b的值为0。所以,如果我们判断一个BOOL值是否为真时,不应该通过if(a == YES)这种方式来判断,要么直接就if (a),要么就if (a != NO)

UIImageView显示gif图片有两种方式。当然前提都是先将gif中的每一帧取出来放到一个个UIImage对象中,将这些对象放到一个数组中,如下代码所示。

1
2
3
4
5
6
7
8
9
10
11
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
size_t count = CGImageSourceGetCount(source);

NSMutableArray *images = [NSMutableArray array];
for (size_t i = 0; i < count; i++) {
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen] orientation:UIImageOrientationUp]];
CGImageRelease(image);
}

CFRelease(source)

一种方式是将这些UIImage对象通过UIImage的类方法+animatedImageWithImages:duration:组合成一个UIImage对象,然后赋值给UIImageView对象的image属性。

第二种方式是将UIImage对象的数组赋值给UIImageView对象的animationImages属性,然后调用UIImageView对象的startAnimating方法来启动动画。

当然,两种方式都需要计算duration。

在使用+URLWithString:-initWithString:来创建一个URL对象时,提供的参数字符串必须符合RFC 2396标准Uniform Resource Identifiers (URI): Generic Syntax。而这两个方法又是根据RFC 1738 Uniform Resource Locators (URL)和1808 Relative Uniform Resource Locators两个标准来解析字符串的。故弄玄虚一下。当然我们不需要去了解所有的细节,简单了解一下就行,可以参考一下阮大侠的这篇关于URL编码。

这里要说明的就是:对于我们而言,如果用带有中文的字符串(如“https://www.baidu.com?q=北京”)去创建一个URL对象的话,返回的是一个nil。

我们所需要做的就是对不符合标准的字符串进行转义操作。NSString类提供了两个方法来做这种转义操作,一个是-stringByAddingPercentEscapesUsingEncoding:,不过这个方法在iOS 9.0已被废弃;现在更提倡的是用-stringByAddingPercentEncodingWithAllowedCharacters:方法,这个方法是iOS 7.0后添加的。

1
NSString *urlStr = [@"https://www.baidu.com?q=北京" stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

runtime简介

  • RunTime简称运行时。OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制。
  • 对于C语言,函数的调用在编译的时候会决定调用哪个函数
  • 对于OC的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。
  • 事实证明:
    • 在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要声明过就不会报错。
    • 在编译阶段,C语言调用未实现的函数就会报错。
阅读全文 »