ios之asi和afn有什么区别

关于网络请求,ASIHTTPRequest 库的替代方法
08:34:12 +08:00 · 3328 次点击
关于网络请求,项目原来一直用ASIHTTPRequest库,可是这库好久不更新了,想找个替代方法,貌似知道的只有AFNetworking,还有其他比较好的替换方法没?如何比较这几个库的效率等问题来选择合适的呢?你们项目中是如何挑选解决网络请求问题的呢?谢谢喽~
13 回复 &| &直到
08:00:00 +08:00
& & 08:35:38 +08:00
一直用afnetworking,很好用的
& & 08:39:27 +08:00
AFNetworking. @ 都在用的东西, 你好意思嫌弃?
& & 08:49:39 +08:00
偏向afnetworking,可以arc~~ 。。。。不过我公司还在用asi~~
& & 09:06:51 +08:00
MKNetworkkit
& & 09:23:17 +08:00
AFNetworking+1
& & 09:59:27 +08:00
AFNetworking (强烈推荐)
MKNetworkKit
RestKit
STHTTPRequest
...
关于AFN和ASI的对比:
但是我们一直在用MKNetworkKit,社交类排名挺靠前的App,几年了稳定性是没什么问题。
& & 10:47:58 +08:00
AFNetworking MKNetworkKit
& & 11:06:53 +08:00
restkit用的还是afn 而且是1.x的afn
& & 11:12:39 +08:00
AFNetworking
& & 13:16:35 +08:00
AFNetworking, mattt 的东西易用性和质量都没的说
& & 15:42:50 +08:00
AFNetworking
& & 19:51:12 +08:00
afnetworking+1
& & 00:57:26 +08:00
千万别用!
基本上都是 AFN吧。。。。
& · & 675 人在线 & 最高记录 3541 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.0 · 55ms · UTC 18:40 · PVG 02:40 · LAX 10:40 · JFK 13:40? Do have faith in what you're doing.下次自动登录
现在的位置:
& 综合 & 正文
网络编程之AFNetwork
&&&&推荐文章:
【上篇】【下篇】开发经验:对AFN和ASI各自使用方法及区别的总结_iOS开发_动态网站制作指南
开发经验:对AFN和ASI各自使用方法及区别的总结
来源:人气:1484
经过多年的iOS开发, 现总结一下HTTP协议下的两大网络处理第三方框架的使用心得
首先来说下AFNetworking:
一、2大管理对象1.AFHTTequesttionManager* 对NSURLConnection的封装
2.AFHTTPManager* 对NSURLSession的封装
二、AFHTTPRequestOperationManager的具体使用1.创建管理者AFHTTPRequestOperationManager \*mgr = [AFHTTPRequestOperationManager manager];
2.封装请求参数
NSMutableDictionary \*params = [NSMutableDictionary dictionary];
params[@&username&] = @&哈哈&;
params[@&pwd&] = @&123&;
3.发送请求
NSString *url = @&http://localhost:8080/LWServer/login&;
[mgr POST:url parameters:params
success:^(AFHTTPRequestOperation \*operation, id responbject) {
// 请求成功的时候调用这个block
NSLog(@&请求成功---%@&, responseObject);
} failure:^(AFHTTPRequestOperation \*operation, NSError *error) {
// 请求失败的时候调用调用这个block
NSLog(@&请求失败&);
// GET请求
[mgr GET:url parameters:params
success:^(AFHTTPRequestOperation \*operation, id responseObject) {
// 请求成功的时候调用这个block
NSLog(@&请求成功---%@&, responseObject);
} failure:^(AFHTTPRequestOperation \*operation, NSError *error) {
// 请求失败的时候调用调用这个block
NSLog(@&请求失败&);
三、对服务器返回数据的解析1.AFN可以自动对服务器返回的数据进行解析* 默认将服务器返回的数据当做JSON来解析
2.设置对服务器返回数据的解析方式1& 当做是JSON来解析(默认做法)* mgr.responseSerializer = [AFJSONResponseSerializer serializer];* responseObject的类型是NSDictionary或者NSArray
2& 当做是来解析* mgr.responseSerializer = [AFXMLParserResponseSerializer serializer];* responseObject的类型是NSXMLParser
3& 直接返回data* 意思是:告诉AFN不要去解析服务器返回的数据,保持原来的data即可* mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
3.注意* 服务器返回的数据一定要跟responseSerializer对得上1& 服务器返回的是JSON数据* AFJSONResponseSerializer* AFHTTPResponseSerializer
2& 服务器返回的是XML数据* AFXMLParserResponseSerializer* AFHTTPResponseSerializer
3& 服务器返回的是其他数据* AFHTTPResponseSerializer
其次说下是asi-http-request:
一、发送请求的2个对象1.发送GET请求:ASIHttpRequest
2.发送POST请求:ASIFormDataRequest* 设置参数
// 同一个key只对应1个参数值,适用于普通“单值参数”
- (void)setPostValue:(id &NSObject&)value forKey:(NSString \*)key
// 同一个key(同一个参数名),会对应多个参数值,适用于“多值参数”
- (void)addPostValue:(id &NSObject&)value forKey:(NSString \*)key
二、发送请求1.同步请求* startSynchronous
2.异步请求* startAsynchronous
三、监听请求的过程1.如何监听请求过程1& 为代理,遵守&ASIHTTPRequestDelegate&协议,实现协议中的代理方法
request.delegate =
- (void)requestStarted:(ASIHTTPRequest *)
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseH
- (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)
- (void)requestFinished:(ASIHTTPRequest *)
- (void)requestFailed:(ASIHTTPRequest *)
2& 成为代理,不遵守&ASIHTTPRequestDelegate&协议,自定义代理方法
request.delegate =
[request setDidStartSelector:@selector(start:)];
[request setDidFinishSelector:@selector(finish:)];
3& 设置block
[request setStartedBlock:^{
NSLog(@&setStartedBlock&);
[request setHeadersReceivedBlock:^(NSDictionary *responseHeaders) {
NSLog(@&setHeadersReceivedBlock--%@&, responseHeaders);
[request setDataReceivedBlock:^(NSData *data) {
NSLog(@&setDataReceivedBlock--%@&, data);
[request setCompletionBlock:^{
NSLog(@&setCompletionBlock&);
[request setFailedBlock:^{
NSLog(@&setFailedBlock&);
2.监听的使用注意* 如果同时设置了block和实现了代理方法,请求过程中,block和代理方法都会调用* 一般的调用顺序:代理方法 & block
3.如果实现了下面的代理方法,那么responseData\responseString就没有值
- (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)
四、文件下载1.一般的下载1& 设置文件下载的保存路径
request.downloadDestinationPath =
2& 设置进度监听的代理(要想成为进度监听代理,最好遵守&ASrogressDelegate&协议)
request.downloadProgressDelegate = self.progressV
2.断点下载(断点续传)1& 设置文件下载的临时路径
request.temporaryFileDownloadPath = tempF
2& 设置支持断点续传
request.allowResumeForFileDownloads = YES;
五、文件上传(设置文件参数)1.如果知道文件路径,最好就用这个方法(因为简单)
// ASI内部会自动识别文件的MIMEType
[request setFile:file forKey:@&file&];
[request addFile:file forKey:@&file&];
[request setFile:file withFileName:@&basic.x& andContentType:@&/vnd.openxmlformats-officedocument.presentationml.presentation& forKey:@&file&];
2.如果文件数据是动态产生的,就用这个方法(比如刚拍照完获得的图片数据)
[request setData:data withFileName:@&test.png& andContentType:@&image/png& forKey:@&file&];
六、ASIHttpRequest的常见用法1.请求超时
@property (atomic, assign) NSTimeInterval timeOutS
2.获得错误信息
@property (atomic, retain) NSError *
3.获得响应数据
@property (atomic, assign,readonly) int responseStatusC
// 状态信息
@property (atomic, retain,readonly) NSString *responseStatusM
// 服务器返回的具体数据(NSString格式)
- (NSString *)responseS
// 服务器返回的具体数据(NSData格式)
- (NSData *)responseD
最后是重点内容,也是面试时经常会问的问题,两者的区别:
一、底层实现1& AFN的底层基于OC的NSURLConnection和NSURLSession2& ASI的底层基于纯C语言的CFNetwork框架3& ASI的运行性能 高于 AFN
二、对服务器返回的数据处理1& ASI没有直接提供对服务器数据处理的方式,直接返回data\string2& AFN提供了多种对服务器数据处理的方式* JSON处理* XML处理* 其他处理
三、监听请求的过程1& AFN提供了success和failure两个block来监听请求的过程(只能监听成功和失败)* success : 请求成功后调用* failure : 请求失败后调用
2& ASI提供了3套方案,每一套方案都能监听请求的完整过程(监听请求开始、接收到响应头信息、接受到具体数据、接受完毕、请求失败)* 成为代理,遵守协议,实现协议中的代理方法* 成为代理,不遵守协议,自定义代理方法* 设置block
四、在文件下载和文件上传的使用难易度1& AFN* 不容易监听下载进度和上传进度* 不容易实现断点续传* 一般只用来下载不大的文件
2& ASI* 非常容易实现下载和上传* 非常容易监听下载进度和上传进度* 非常容易实现断点续传* 下载或大或小的文件都行
五、ASI提供了更多的实用功能1& 控制圈圈要不要在请求过程中转2& 可以轻松地设置请求之间的依赖:每一个请求都是一个NSOperation对象3& 可以统一管理所有请求(还专门提供了一个叫做ASINetworkQueue来管理所有的请求对象)* 暂停\恢复\取消所有的请求* 监听整个队列中所有请求的下载进度和上传进度
优质网站模板本篇将从四个方面对iOS开发中经常使用到的AFNetworking框架进行讲解:
一、什么是 AFN
二、为什么要使用 AFN
三、AFN 怎么用
三、AFN和ASI的区别
一、什么是 ...
目前很多APP都要求支持Https通讯,现在大多APP都是AFN框架之上实现的网络通讯层。
以下讨论了一下,AFN 框架之下,如何实现Http 和 Https兼容(都支持)。(这个知识点虽然不难,但是...
React.native是facebook开源的一套基于JavaScript的开源框架,
很方便用来开发移动设备的app。
而且,方便及时更新app的UI与数据,也很方便部署。
goodmao希望帮助...
React.native是facebook开源的一套基于JavaScript的开源框架,
很方便用来开发移动设备的app。
而且,方便及时更新app的UI与数据,也很方便部署。
goodmao希望帮助...
react.native极大提高开发效率,可以实现跨平台开发,而且很方便从服务器部署app端UI与数据。
goodmao希望大家尽快掌握!...
React.native是facebook开源的一套基于JavaScript的开源框架,
很方便用来开发移动设备的app。
而且,方便及时更新app的UI与数据,也很方便部署。
goodmao希望帮助...
React.native是facebook开源的一套基于JavaScript的开源框架,
很方便用来开发移动设备的app。
而且,方便及时更新app的UI与数据,也很方便部署。
goodmao希望帮助...
React.native是facebook开源基于JavaScript的框架,方便开发移动设备的app。
而且,方便及时更新app的UI与数据,也很方便部署。
goodmao希望帮助大家掌握!...
https://facebook.github.io/react-native/docs/getting-started.html
https://facebook.github.io/...
支持iOS平台设备上的音频即时通讯应用开发提供Objective-C语言API接口,开放示例源代码集成H.264、AAC、AMR等编解码技术封装音视频的采集、编解码、传输、显示和播放等模块支持Andr...
他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)IOS开发使用NSURLConnection、NSURLSession、AFN、ASI四种方式实现HTTP请求
我的图书馆
IOS开发使用NSURLConnection、NSURLSession、AFN、ASI四种方式实现HTTP请求
概括:HTTP请求可以使用NSURLConnection、NSURLSession、AFN、ASI等方式实现,其中又包括了get、post两种请求方式和同步、异步两种程序执行方式。&NSURLConnection1 get方式的同步请求/**&*& get同步请求&*/-(void) getSynch{& &&//&获取URL& &&NSURL&*url = [[NSURL&alloc]&initWithString:@"http://localhost:8070/MJServer/login?username=123&password=123"];& &&//&获取request请求& &&NSURLRequest&*request = [NSURLRequest&requestWithURL:url];&& &&& && &&//&发送同步请求& &&NSData&*data = [NSURLConnection&sendSynchronousRequest:request&returningResponse:nil&error:nil];&& && &&//&将data转换成string& &&NSString&*result = [[NSString&alloc]&initWithData:data&encoding:NSUTF8StringEncoding];&& && &&NSLog(@"data -- %@", result);}&&2 get方式的异步请求/**&*& get异步请求&*/-(void) getAsynch{& &&//&获取URL& &&NSURL&*url = [[NSURL&alloc]&initWithString:@"http://localhost:8070/MJServer/video"];& &&//&获取request请求& &&NSURLRequest&*request = [NSURLRequest&requestWithURL:url];&& && &&//&发送同步请求& & [NSURLConnection&sendAsynchronousRequest:request&queue:[NSOperationQueue&mainQueue]&completionHandler:^(NSURLResponse&*response,&NSData&*data,&NSError&*connectionError) {&& & & && & & &&//&将data数据转成字典& & & &&NSDictionary&*dict = [NSJSONSerialization&JSONObjectWithData:data&options:NSJSONReadingAllowFragments&error:nil];& & & &&NSLog(@"data -- %@", dict);& & }];}&3 post同步请求/**&*& post同步请求&*/-(void) postSynch{& &&//&获取URL& &&NSURL&*url = [[NSURL&alloc]&initWithString:@"http://localhost:8070/MJServer"];&& && &&//&设置post请求需要使用NSMutableURLRequest& &&NSMutableURLRequest&*request = [NSMutableURLRequest&requestWithURL:url];& &&//&设置请求方式为post (必选)& & request.HTTPMethod&=&@"POST";&& &&//&发送同步请求& &&NSData&*data = [NSURLConnection&sendSynchronousRequest:request&returningResponse:nil&error:nil];&& && &&//&将data转换成string& &&NSString&*result = [[NSString&alloc]&initWithData:data&encoding:NSUTF8StringEncoding];&& && &&NSLog(@"data -- %@", result);&& &}&4 post异步请求/**&*& post异步请求&*/-(void) postAsynch{& &&//&获取URL& &&NSURL&*url = [[NSURL&alloc]&initWithString:@"http://localhost:8070/MJServer/login"];& &&//&获取request请求& &&NSMutableURLRequest&*request = [NSMutableURLRequest&requestWithURL:url];& &&//&设置请求方式为post& & request.HTTPMethod&=&@"POST";&& && &&//&设置表单参数&(可选)& &&NSString&*params = [NSString&stringWithFormat:@"username=123&pwd=123"];& & request.HTTPBody&= [params&dataUsingEncoding:NSUTF8StringEncoding];&& && &&//&设置超时(可选)& & request.timeoutInterval&=&5;&& && &&//&设置请求头信息(可选)& & [request&setValue:@"iPhone 6"&forHTTPHeaderField:@"User-Agent"];&& && &&//&设置post请求需要使用NSMutableURLRequest& & [NSURLConnection&sendAsynchronousRequest:request&queue:[NSOperationQueue&mainQueue]&completionHandler:^(NSURLResponse&*response,&NSData&*data,&NSError&*connectionError) {&& & & && & & &&//&将data数据转成字典& & & &&NSDictionary&*dict = [NSJSONSerialization&JSONObjectWithData:data&options:NSJSONReadingAllowFragments&error:nil];& & & &&NSLog(@"data -- %@", dict);& & }];}&NSURLSession1 session的get请求/**&*& session的get请求&*/-(void) sessionGet{& &&//&获取一个session实例& &&NSURLSession&*session = [NSURLSession&sharedSession];&& && &&//&获取url& &&NSURL&*url = [[NSURL&alloc]&initWithString:@"http://localhost:8070/MJServer/video"];& &&//&创建一个数据访问任务& &&NSURLSessionDataTask&*task = [session&dataTaskWithURL:url&completionHandler:^(NSData&*data,&NSURLResponse&*response,&NSError&*error) {& & & &&NSLog(@"data -- %@", [[NSString&alloc]&initWithData:data&encoding:NSUTF8StringEncoding]);& & }];& &&//&启动任务,开始、回复都用resume& & [task&resume];}&2 session的post请求/**&*& session的post请求&*/-(void) sessionPost{& &&//&获取一个session实例& &&NSURLSession&*session = [NSURLSession&sharedSession];&& && &&//&获取url& &&NSURL&*url = [[NSURL&alloc]&initWithString:@"http://localhost:8070/MJServer/login"];& &&//&获取request请求对象& &&NSMutableURLRequest&*request = [NSMutableURLRequest&requestWithURL:url];& &&//&设置请求方式& & request.HTTPMethod&=&@"POST";& &&//&设置请求体,& &&NSString&*params =&@"username=123&pwd=123";& & request.HTTPBody&= [params&dataUsingEncoding:NSUTF8StringEncoding];&& && &&//&创建一个数据访问任务& &&NSURLSessionDataTask&*task = [session&dataTaskWithRequest:request&completionHandler:^(NSData&*data,&NSURLResponse&*response,&NSError&*error) {& & & &&NSLog(@"data -- %@", [[NSString&alloc]&initWithData:data&encoding:NSUTF8StringEncoding]);& & }];&& && &&//&开始任务& & [task&resume];}&AFNetwork框架,需要导入#import&"AFNetworking.h"1 AFN的get请求#import&"AFNetworking.h"/**&*& afn的get请求&*/-(void) afnGet{& &&//&创建一个请求操作管理者& &&AFHTTPRequestOperationManager&*manager = [AFHTTPRequestOperationManager&manager];&& &&//&声明响应结果不进行json、xml等格式解析,直接返回data& & manager.responseSerializer&= [AFHTTPResponseSerializer&serializer];&& && &&//&设置请求参数(可选)& &&NSMutableDictionary&*params = [NSMutableDictionary&dictionary];& & params[@"username"] =&@"123";& & params[@"pwd"] =&@"123";&& &&& && &&//&发送get请求& &&NSString&*url =&@"http://localhost:8070/MJServer/login";& & [manager&GET:url&parameters:params&success:^(AFHTTPRequestOperation&*operation,&id&responseObject) {& & & &&//&请求成功在这里处理& & & &&//&将响应数据转换成字典& & & &&NSDictionary&*dict = [NSJSONSerialization&JSONObjectWithData:responseObject&options:NSJSONReadingAllowFragments&error:nil];& & & &&NSLog(@"%@", dict);&& && & }&failure:^(AFHTTPRequestOperation&*operation,&NSError&*error) {& & & &&//&如果请求失败在这里处理& & & &&NSLog(@"request fail");& & }];}&2 AFN的post请求/**&*& afn的post请求&*/-(void) afnPost{& &&//&创建一个请求操作管理者& &&AFHTTPRequestOperationManager&*manager = [AFHTTPRequestOperationManager&manager];&& && &&//&声明响应结果不进行json、xml等格式解析,直接返回data& & manager.responseSerializer&= [AFHTTPResponseSerializer&serializer];&& && &&//&设置请求参数(可选)& &&NSMutableDictionary&*params = [NSMutableDictionary&dictionary];& & params[@"username"] =&@"123";& & params[@"pwd"] =&@"123";&& &&& && &&//&发送get请求& &&NSString&*url =&@"http://localhost:8070/MJServer/login";& & [manager&POST:url&parameters:params&success:^(AFHTTPRequestOperation&*operation,&id&responseObject) {& & & &&//&请求成功在这里处理& & & &&//&将响应数据转换成字典& & & &&NSDictionary&*dict = [NSJSONSerialization&JSONObjectWithData:responseObject&options:NSJSONReadingAllowFragments&error:nil];& & & &&NSLog(@"%@", dict);&& & & && & }&failure:^(AFHTTPRequestOperation&*operation,&NSError&*error) {& & & &&//&如果请求失败在这里处理& & & &&NSLog(@"request fail");& & }];}&ASI(注意添加libz类库并修改ASI源文件为非arc)1 ASI的get同步请求#import&"ASIHTTPRequest.h"/**&*& ASI的get同步请求&*/-(void) asiGetSynch{& &&//&获取url& &&NSURL&*url = [[NSURL&alloc]&initWithString:@"http://localhost:8070/MJServer/video"];&& && &&//&获取asi请求对象& &&ASIHTTPRequest&*request = [ASIHTTPRequest&requestWithURL:url];& &&//&发送同步请求& & [request&startSynchronous];&& && &&NSError&*error = [request&error];& &&if&(error) {& & & &&NSLog(@"请求失败");& & }else{//& & & & NSString *data = [request responseString];& & & &&NSData&*data = [request&responseData];& & & &&NSDictionary&*result = [NSJSONSerialization&JSONObjectWithData:data&options:NSJSONReadingAllowFragments&error:nil];& & & &&NSLog(@"result -- %@", result);& & }}&2 ASI的get异步请求/**&*& ASI的get异步请求&*&&须知:ASI监听请求过程有delegate、block和selector三种方式,&*&&经测试发现,delegate和block可以同时执行,selector和block也可以同时执行,但delegate和selector共存时(包括三者共存)不执行delegate&*&&执行顺序:delegate & selector & block&*&&通过responseData和responseString获取不到数据&* &使用了代理就不能直接通过responseData和responseString获取到数据&*/-(void) asiGetAsynch{& &&//&获取url& &&NSURL&*url = [[NSURL&alloc]&initWithString:@"http://localhost:8070/MJServer/video"];&& && &&//&获取asi请求对象& &&ASIHTTPRequest&*request = [ASIHTTPRequest&requestWithURL:url];&& && &&//&设置ASIHTTPRequestDelegate代理。& & request.delegate&=&&& && &&//&发送异步请求& & [request&startAsynchronous];&& &&//&设置监听请求过程的block& & [request&setStartedBlock:^{& & & &&NSLog(@"block请求开始");& & }];&& && & [request&setDataReceivedBlock:^(NSData&*data) {& & & &&NSLog(@"block获得请求数据&-- %@", [NSJSONSerialization&JSONObjectWithData:data options:NSJSONReadingAllowFragments&error:nil]);& & }];&& & [request&setCompletionBlock:^{& & & &&NSLog(@"block请求结束");& & }];&& && &&//&设置监听请求过程的selector& & [request&setDidStartSelector:@selector(start:)];& & [request&setDidReceiveDataSelector:@selector(receiveData:)];& & [request&setDidFinishSelector:@selector(finish:)];&}&#pragma mark selector监听方法-(void)start:(ASIHTTPRequest&*)request{& &&NSLog(@"selector请求开始");}&-(void) receiveData:(ASIHTTPRequest&*) request{& &&//&这里获取不到数据& &&NSLog(@"selector获得请求数据&-- %@", [request&responseString]);}&&-(void)finish:(ASIHTTPRequest&*)request{& &&NSLog(@"selector请求结束");}&#pragma mark&实现ASIHTTPRequestDelegate的代理方法- (void)request:(ASIHTTPRequest&*)request didReceiveData:(NSData&*)data{&& &&NSLog(@"delegate获得请求数据&-- %@", [NSJSONSerialization&JSONObjectWithData:data options:NSJSONReadingAllowFragments&error:nil]);}&- (void)requestStarted:(ASIHTTPRequest&*)request{&& && &&NSLog(@"delegate请求开始");}&- (void)requestFinished:(ASIHTTPRequest&*)request{& &&NSLog(@"delegate请求结束");}&- (void)requestFailed:(ASIHTTPRequest&*)request{& &&NSLog(@"delegate请求失败");}&3 ASI的post异步请求#import&"ASIFormDataRequest.h"/**&*& ASI的post异步请求&*/-(void) asiPostAsynch{&& && &&//&获取url& &&NSURL&*url = [[NSURL&alloc]&initWithString:@"http://localhost:8070/MJServer/login"];&& && &&//&获取ASI表单请求对象& &&ASIFormDataRequest&*request = [ASIFormDataRequest&requestWithURL:url];&& && &&//&设置请求参数& & [request&setPostValue:@"123"&forKey:@"username"];& & [request&setPostValue:@"123"&forKey:@"pwd"];&& && &&//&使用了代理就不能直接通过responseData和responseString获取数据//& & request.delegate =&& && &&//&发送异步请求& & [request&startAsynchronous];&& && &&//&设置监听(这里只演示block方法)& &&__weak&ASIFormDataRequest&*req =& & [request&setCompletionBlock:^{& & & &&NSLog(@"selector获得请求数据&-- %@", [req&responseString]);& & }];}&
TA的最新馆藏[转]&[转]&[转]&[转]&
喜欢该文的人也喜欢

我要回帖

更多关于 安卓和ios区别 的文章

 

随机推荐