IOS 开发 网络详解(二)

NSURLSesstion

NSURLConnection在IOS2出现,在iOS9被宣布弃用,NSURLSession从13年发展到现在,终于迎来了它独步江湖的时代.NSURLSession是苹果在iOS7后为HTTP数据传输提供的一系列接口,比NSURLConnection强大,坑少,好用.今天从使用的角度介绍下.
使用NSURLSession,拢共分两步:

第一步 通过NSURLSession的实例创建task
第二部 执行task
既然两步里面都出现了task,就先说说它吧.

NSURLSessionTask可以简单理解为任务:如数据请求任务,下载任务,上传任务and so on.我们使用的是他的子类们:

NSURLSessionTask(抽象类)
NSURLSessionDataTask
NSURLSessionUploadTask
NSURLSessionDownloadTask
从这几个子类的名字就可以大概猜出他们的作用了.接下来我们就从不同类型的任务出发,来使用session.
NSURLSessionDataTask

字面上看是和数据相关的任务,但其实dataTask完全可以胜任downloadTask和uploadTask的工作.这可能也是我们使用最多的task种类.

简单GET请求

如果请求的数据比较简单,也不需要对返回的数据做一些复杂的操作.那么我们可以使用带block

// 快捷方式获得session对象
NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:@"http://www.daka.com/login?username=daka&pwd=123"];
// 通过URL初始化task,在block内部可以直接对返回的数据进行处理
NSURLSessionTask *task = [session dataTaskWithURL:url
                               completionHandler:^(NSData *data, NSURLResponse *response, NSError error) {
    NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];

// 启动任务
[task resume];
Tips:

所有类型的task都要调用resume方法才会开始进行请求.
简单POST请求

POST和GET的区别就在于request,所以使用session的POST请求和GET过程是一样的,区别就在于对request的处理.

NSURL *url = [NSURL URLWithString:@"http://www.daka.com/login"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=daka&pwd=123" dataUsingEncoding:NSUTF8StringEncoding];

NSURLSession *session = [NSURLSession sharedSession];
// 由于要先对request先行处理,我们通过request初始化task
NSURLSessionTask *task = [session dataTaskWithRequest:request
                                   completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]); }];
[task resume];
NSURLSessionDataDelegate代理方法
NSURLSessionDataDelegate代理方法

NSURLSession提供了block方式处理返回数据的简便方式,但如果想要在接收数据过程中做进一步的处理,仍然可以调用相关的协议方法.NSURLSession的代理方法和NSURLConnection有些类似,都是分为接收响应、接收数据、请求完成几个阶段.

// 使用代理方法需要设置代理,但是session的delegate属性是只读的,要想设置代理只能通过这种方式创建session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                                                      delegate:self
                                                 delegateQueue:[[NSOperationQueue alloc] init]];

// 创建任务(因为要使用代理方法,就不需要block方式的初始化了)
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.daka.com/login?userName=daka&pwd=123"]]];

// 启动任务
[task resume];

//对应的代理方法如下:

// 1.接收到服务器的响应
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    // 允许处理服务器的响应,才会继续接收服务器返回的数据
    completionHandler(NSURLSessionResponseAllow);
}

// 2.接收到服务器的数据(可能调用多次)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    // 处理每次接收的数据
}

// 3.请求成功或者失败(如果失败,error有值)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    // 请求完成,成功或者失败的处理
}
简单下载

NSURLSessionDownloadTask同样提供了通过NSURL和NSURLRequest两种方式来初始化并通过block进行回调的方法.下面以NSURL初始化为例:

SURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:@"http://www.daka.com/resources/image/icon.png"] ;
NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
    // location是沙盒中tmp文件夹下的一个临时url,文件下载后会存到这个位置,由于tmp中的文件随时可能被删除,所以我们需要自己需要把下载的文件挪到需要的地方
    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
    // 剪切文件
    [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:path] error:nil];
}];
    // 启动任务
    [task resume];

简单的上传

NSURLSessionUploadTask *task =
[[NSURLSession sharedSession] uploadTaskWithRequest:request
                                           fromFile:fileName
                                  completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
}];
和

 [self.session uploadTaskWithRequest:request
                            fromData:body
                   completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
 NSLog(@"-------%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
 }];

断点续传
其他

此外,task们自身有都拥有下面几个方法

- (void)suspend;
- (void)resume;
- (void)cancel;
suspend可以让当前的任务暂停

resume方法不仅可以启动任务,还可以唤醒suspend状态的任务

cancel方法可以取消当前的任务,你也可以向处于suspend状态的任务发送cancel消息,任务如果被取消便不能再恢复到之前的状态.
NSURLSessionConfiguration

简单地说,就是session的配置信息.如:

NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
// 超时时间
config.timeoutIntervalForRequest = 10;
// 是否允许使用蜂窝网络(后台传输不适用)
config.allowsCellularAccess = YES;
// 还有很多可以设置的属性
有没有发现我们使用的Configuration都是默认配置:[NSURLSessionConfiguration defaultSessionConfiguration],其实它的配置有三种类型:

+ (NSURLSessionConfiguration *)defaultSessionConfiguration;
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier
表示了NSURLSession几种不同的工作模式.
默认的配置会将缓存存储在磁盘上,第二种瞬时会话模式不会创建持久性存储的缓存,第三种后台会话模式允许程序在后台进行上传下载工作.

除了支持任务的暂停和断点续传,我觉得NSURLSession之于NSURLConnection的最伟大的进步就是支持后台上传下载任务,这又是一个可以深入讨论的话题.但在这方面我还没有进行深入的研究,待后续了解之后另行开贴.

ASI

同步请求:

发起一个同步请求

同步意为着线程阻塞,在主线程中使用此方法会使应用Hang住而不响应任何用户事件。所以,在应用程序设计时,大多被用在专门的子线程增加用户体验,或用异步请求代替(下面会讲到)。
- (IBAction)grabURL:(id)sender
{
  NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  [request startSynchronous];
  NSError *error = [request error];
  if (!error) {
    NSString *response = [request responseString];
  }
}

异步请求:

创建一个异步请求

异步请求的好处是不阻塞当前线程,但相对于同步请求略为复杂,至少要添加两个回调方法来获取异步事件。
下面异步请求代码完成上面同样的一件事情:
- (IBAction)grabURLInBackground:(id)sender
{
   NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
   ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
   [request setDelegate:self];
   [request startAsynchronous];
}

- (void)requestFinished:(ASIHTTPRequest *)request
{
   // Use when fetching text data
   NSString *responseString = [request responseString];

   // Use when fetching binary data
   NSData *responseData = [request responseData];
}

- (void)requestFailed:(ASIHTTPRequest *)request
{
   NSError *error = [request error];
}

队列请求:

队列请求

提供了一个对异步请求更加精准丰富的控制。
如,可以设置在队列中,同步请求的连接数。往队列里添加的请求实例数大于maxConcurrentOperationCount时,请求实例将被置为等待,直到前面至少有一个请求完成并出列才被放到队列里执行。
也适用于当我们有多个请求需求按顺序执行的时候(可能是业务上的需要,也可能是软件上的调优),仅仅需要把maxConcurrentOperationCount设为“1”。
- (IBAction)grabURLInTheBackground:(id)sender
{
   if (![self queue]) {
      [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
   }

   NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
   ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
   [request setDelegate:self];
   [request setDidFinishSelector:@selector(requestDone:)];
   [request setDidFailSelector:@selector(requestWentWrong:)];
   [[self queue] addOperation:request]; //queue is an NSOperationQueue
}

- (void)requestDone:(ASIHTTPRequest *)request
{
   NSString *response = [request responseString];
}

- (void)requestWentWrong:(ASIHTTPRequest *)request
{
   NSError *error = [request error];
}
创建NSOperationQueue,这个Cocoa架构的执行任务(NSOperation)的任务队列。我们通过ASIHTTPRequest.h的源码可以看到,此类本身就是一个NSOperation的子类。也就是说它可以直接被放到"任务队列"中,并被执行。上面的代码队了队列的创建与添加操作外,其它代码与上一例一样。

上传:

向服务器端上传数据

ASIFormDataRequest ,模拟 Form表单提交,其提交格式与 Header会自动识别。
没有文件:application/x-www-form-urlencoded
有文件:multipart/form-data
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:@"Ben" forKey:@"first_name"];
[request setPostValue:@"Copsey" forKey:@"last_name"];
[request setFile:@"/Users/ben/Desktop/ben.jpg" forKey:@"photo"];
[request addData:imageData withFileName:@"george.jpg" andContentType:@"image/jpeg" forKey:@"photos"];

下载:

1.创建请求队列:

首先,创建网络请求队列,如下:
ASINetworkQueue   *que = [[ASINetworkQueue alloc] init];
self.netWorkQueue = que;
[que release];

[self.netWorkQueue reset];
[self.netWorkQueue setShowAccurateProgress:YES];
[self.netWorkQueue go];

2.设置存放路径

//初始化Documents路径
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
//初始化临时文件路径
NSString *folderPath = [path stringByAppendingPathComponent:@"temp"];
//创建文件管理器
NSFileManager *fileManager = [NSFileManager defaultManager];
//判断temp文件夹是否存在
BOOL fileExists = [fileManager fileExistsAtPath:folderPath];

if (!fileExists) {//如果不存在说创建,因为下载时,不会自动创建文件夹
[fileManager createDirectoryAtPath:folderPath
           withIntermediateDirectories:YES
                            attributes:nil
                                 error:nil];

3.发送请求

这里对下面几个对象说明一下:CustomCell是我自定义的cell,cell上面有下载和暂停两个按钮,其tag值为cell所在的行,因此这里的[sendertag]为下载按钮的tag值,self.downloadArray为array数组对象,存放要下载的资源字典信息,在该字典中有一键为URL,它对应的值就是我们下载链接。
这些东西,根据自己的实际需要改动一下即可使用

CustomCell *cell = (CustomCell *)[self.myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:[sender tag] inSection:0]];
NSString  *filePath = [[self.downloadArray objectAtIndex:[sender tag]] objectForKey:@"URL"];
NSLog(@"filePath=%@",filePath);
//初始下载路径
NSURL *url = [NSURL URLWithString:filePath];
//设置下载路径
ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:url];
//设置ASIHTTPRequest代理
request.delegate = self;
//初始化保存ZIP文件路径
NSString *savePath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"book_%d.zip",[sender tag]]];
//初始化临时文件路径
NSString *tempPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"temp/book_%d.zip.temp",[sender tag]]];
//设置文件保存路径
[request setDownloadDestinationPath:savePath];
//设置临时文件路径
[request setTemporaryFileDownloadPath:tempPath];

//设置进度条的代理,
[request setDownloadProgressDelegate:cell];
//设置是是否支持断点下载
[request setAllowResumeForFileDownloads:YES];
//设置基本信息
[request setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:[sender tag]],@"bookID",nil]];

NSLog(@"UserInfo=%@",request.userInfo);
//添加到ASINetworkQueue队列去下载
[self.netWorkQueue addOperation:request];
//收回request
[request release];
/ASIHTTPRequestDelegate,下载之前获取信息的方法,主要获取下载内容的大小,可以显示下载进度多少字节
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders {
 NSLog(@"didReceiveResponseHeaders-%@",[responseHeaders valueForKey:@"Content-Length"]);

    NSLog(@"contentlength=%f",request.contentLength/1024.0/1024.0);
    int bookid = [[request.userInfo objectForKey:@"bookID"] intValue];
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    float tempConLen = [[userDefaults objectForKey:[NSString stringWithFormat:@"book_%d_contentLength",bookid]] floatValue];
    NSLog(@"tempConLen=%f",tempConLen);
    //如果没有保存,则持久化他的内容大小
    if (tempConLen == 0 ) {//如果没有保存,则持久化他的内容大小
        [userDefaults setObject:[NSNumber numberWithFloat:request.contentLength/1024.0/1024.0] forKey:[NSString stringWithFormat:@"book_%d_contentLength",bookid]];
    }

}
//ASIHTTPRequestDelegate,下载完成时,执行的方法
- (void)requestFinished:(ASIHTTPRequest *)request {

int bookid = [[request.userInfo objectForKey:@"bookID"] intValue];
CustomCell *cell = (CustomCell *)[self.myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:bookid inSection:0]];
cell.downloadCompleteStatus = YES;
cell.progressView.progress = 0.0;
}

作者:风继续吹0
链接:https://www.jianshu.com/p/c24cad69f89c
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

AF2.0

1.实现请求的方法

2. 实现

NSURLConnection (iOS 6 & 7)

AFURLConnectionOperation – 它继承于 NSOperation,负责管理 NSURLConnection,实现它的 delegate 方法。
AFHTTPRequestOperation – 它继承于 AFURLConnectionOperation,专门用于创建 HTTP 请求。2.0 的主要区别就是可以直接使用它,而不用再继承它,原因将会在下面的 Serialization 处解释。
AFHTTPRequestOperationManager – 封装 HTTP 请求的常见方式,GET / POST / PUT / DELETE / PATCH……
NSURLSession (iOS 7)

AFURLSessionManager – 创建和管理 NSURLSession 对象,以及此对象的数据和下载/上传等任务,实现对象和任务的代理方法。NSURLSession 的 API 本身有一些局限,AFURLSessionManager 能使其变得更好用。
AFHTTPSessionManager – 它继承于 AFURLSessionManager,封装了 HTTP 请求的常见方式,GET / POST / PUT / DELETE / PATCH……

总的来说:为了支持最新的 NSURLSession 接口,同时兼容旧的 NSURLConnection,2.0 的核心组件将“网络请求”和“任务处理”分离。 AFHTTPRequestOperationManager 和 AFHTTPSessionManager 提供相似的功能,切换很方便,所以从 iOS 6 移植到 iOS 7 会很容易。之前绑在 AFHTTPClient 里的 serialization、security 和 reachability 模型都被分离了出来,基于 NSURLSession 和 NSURLConnection 的 API 都可复用这些模型。

2.AFURLRequestserializtion(序列化)

概述:

RequestSerilization 是AFNetwroking中对网络请求中request这个概率的封装。它的原型其实是NSURLRequest,将NSURLRequest进行第二次封装,将许多诸如请求头,请求参数格式化, multipar/form data文件上传等进行了简化处理。
总结来说,使用AFURLRequestSerializer有以下几个优点:
1?自动处理的请求参数转义,以及对不同请求方式自动对请求参数进行格式化。
2?实现了multipart/form-data方式的请求。
3?自动处理了User-Agent,Language等请求头。

使用:

AFURLRequestSerializtion在AF框架中是封装请求这一部分对象的,作为AFHTTPSessionManaager的一个属性被使用。
如:

 ///    request data parse
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.requestSerializer.timeoutInterval = 30.f;
如果上传时使用的是json格式数据,那么使用AFJSONRequestSerializer:

 manager.requestSerializer = [AFJSONRequestSerializer serializer];
原来存在于NSURLRequest对象的属性,都可以该对象使用如:

[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"accept"];
序列化(Serialization)

2.0 架构的一个突破就是,请求和解析的可序列化。序列化的灵活性允许在网络层添加更多的商业逻辑,自定义更方便。<AFURLRequestSerializer> 和 <AFURLResponseSerializer> 这两个协议,让你在 1.0 中的一些抱怨不复存在。

3.安全

安全

AFNetworking 支持 SSL pinning。这对涉及敏感数据的 App 很重要。

AFSecurityPolicy – 这个类通过特定证书和公共密钥评估链接的安全性和可信任度。在你的 App bundle 中添加服务器证书有助于防止“中间人攻击”。

4.

可达性(Reachability)

另一个从 AFHTTPClient 中分离的功能是网络的可达性。现在你可以单独使用它,或者作为 AFHTTPRequestOperationManager / AFHTTPSessionManager 的一个属性。

AFNetworkReachabilityManager – 负责监控当前的网络可达性,当网络的可达性发生改变时,提供相应的 callback 和通知。
UIKit 扩展

2.0 的中所有 UIKit 扩展都被分离出来并进行了增强。

AFNetworkActivityIndicatorManager: 新增自动开始或结束状态栏上的网络指示器。
UIImageView+AFNetworking: 新增显示图片前剪裁或者加滤镜的功能。
UIButton+AFNetworking (新增): 类似 UIImageView+AFNetworking,按钮的背景图从线上下载。
UIActivityIndicatorView+AFNetworking (新增): 根据网络请求的状态自动开始或结束。
UIProgressView+AFNetworking (新增): 自动跟踪某个请求的上传下载的进度。
UIWebView+AFNetworking (新增): 支持网络请求的进度和内容转换。

5.集成

在 CocoaPods 中使用 AFNetworking 2.0:

platform :ios, ‘7.0‘
pod "AFNetworking", "2.0.0"

6.代码

AFHTTPRequestOperation *request = [[AFHTTPRequestOperation alloc] initWithRequest:urlrequest];

request.responseSerializer = [AFJSONResponseSerializer serializer];
//设置回调的queue,默认是在mainQueue执行block回调
request.completionQueue = your_request_operation_completion_queue();
[request setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
         //设置了‘completionQueue‘后,就可以在这里处理复杂的逻辑
         //不用担心block住了主线程
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

 }];
 [request start];
时间: 2024-10-11 06:10:13

IOS 开发 网络详解(二)的相关文章

IOS 开发 网络详解(十二)AFNetworking总结

AFNetworking是很多公司网络框架的标配,其基本的结构如下: AF包括以下五个模块 网络通信模块(NSURLSession) 网络状态监听模块(Reachability) 网络通信安全策略模块(Security) 网络通信信息序列化/反序列化模块(Serialization) 对于iOS UIKit库的扩展(UIKit) 核心主要是通信模块,其他模块只是为了配合session以及对uikit的扩展,各个模块的关系如下: AFNetworking模块结构图 好了,现在我们通过AF的基本使用

IOS 开发 网络详解(七)--- AFNetworkReachabilityManager

概述 1.因为这个类钥引入(System Configtion)的类库,这个类的使用时基于System Configtion的 2.主要是使用SC(System Configtion)的缩写,SCNetReachablity 3.使用adress 0.0.0.0 ,createArdess获取SCRRef引用 4.使用getflags方法获取网络状态 5.网络状态的枚举.AFRStatues,几种对应的状态,可以扩充 6.只读属性,currentStatus,isWaan,isWifi,isRe

IOS 开发 网络详解(九)--- AFSecurityPolicy解析

下边的这个枚举值的意思的是: 1. AFSSLPinningModeNone 代表无条件信任服务器的证书 2. AFSSLPinningModePublicKey 代表会对服务器返回的证书中的PublicKey进行验证,通过则通过,否则不通过 3. AFSSLPinningModeCertificate 代表会对服务器返回的证书同本地证书全部进行校验,通过则通过,否则不通过 常用的属性 常用的方法 使用的方法 AFHTTPRequestOperationManager *manager = [A

IOS开发 网络详解(三)--- Http请求报文和响应报文(Get和Post)

HTTP请求报文由请求行,请求头,空格和请求数据构成. 1.请求行由请求方法 空格 请求url 空格 版本 组成 2.请求头由关键字/值组成 常用的由user-Agent:浏览器类型 accept:客户端能识别的类型列表 host:主机名 3.空格:区分不同的部分 4.只用post才有:最常对应的请求头尾content-length,content-type 5.get请求实例 //请求首行 GET /hello/index.jsp HTTP/1.1 //请求头信息,因为GET请求没有正文 Ho

IOS 开发 网络详解(八)--- AFSecurityPolicy

1.获取证书 1.获取到站点的证书: ??我们可以使用以下openssl命令来获取到服务器的公开二进制证书(以google为例): "openssl s_client -connect www.google.com:443 </dev/null 2>/dev/null | openssl x509 -outform DER > https.cer" 冒号中的为命令主要部分.该条命令将会在当前路径下,形成google.com站点的公开二进制证书,命名为https.cer

iOS开发- UICollectionView详解+实例

iOS开发- UICollectionView详解+实例 本章通过先总体介绍UICollectionView及其常用方法,再结合一个实例,了解如何使用UICollectionView. UICollectionView 和 UICollectionViewController 类是iOS6 新引进的API,用于展示集合视图,布局更加灵活,可实现多列布局,用法类似于UITableView 和 UITableViewController 类. 使用UICollectionView 必须实现UICol

iOS开发 - UIActivityViewController详解

昨天在做微信分享的时候, 用到了这个东西.趁热写点东西记录下. UIActivityViewController类是一个标准的view controller,通个使用这个controller,你的应用程序就可以提供各种服务. 系统提供了一些通用的标准服务,例如拷贝内容至粘贴板.发布一个公告至社交网.通过email或者SMS发送内容. 应用程序同样可以自定义服务.(我的微信分享就属于自定义服务, 之后将会写一篇教程介绍) 你的应用程序负责配置.展现和解雇这个view controller. vie

iOS开发:详解Objective-C runTime

Objective-C总Runtime的那点事儿(一)消息机制 最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎必问,例如:RunLoop,Block,内存管理等.其他的问题如果有机会我会在其他文章中介绍. 本篇文章主要介绍RunTime. RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编

IOS开发 Blocks详解(转)

IOS开发 Blocks详解(转) (2013-10-14 16:41:54) 从Mac OS X 10.6以及iOS 4开始,苹果在GCC和Clang编译器中为C语言引入了一个新扩展:Blocks,使得程序员可以在C.Objective-C.C++和Objective-C中使用闭包.Blocks有点像函数,但是它可以在其它函数或方法中进行声明和定义,同时它还是匿名的(匿名函数),并可以捕获其所在作用域中的变量(闭包特性). Blocks的语法 Blocks和C语言中的函数指针有点类似,如果你了