iOS笔记7

本文介绍了iOS开发中网络编程的基础知识,包括GCD和NSOperation的使用、HTTP请求方法HEAD的应用、文件分段下载的实现及数据写入文件的方法。此外还探讨了Objective-C runtime的概念及其用途。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、GCD和NSOperation 调用主线程
 在网络开发中,但是最容易出现问题的地方就容易忘记在主线程更新UI
 此处如果使用NSOperation mainQueue是等效的
  dispatch_async(dispatch_get_main_queue(), ^{
            [[NSOperationQueue mainQueue] addOperationWithBlock: ^ {

2、 专门针对中文编码不正确
- (NSString *)descriptionWithLocale:(id)locale
{
    NSMutableString *strM = [NSMutableString stringWithString:@"(\n"];
    
    [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        [strM appendFormat:@"\t%@,\n", obj];
    }];
    
    [strM appendString:@")"];
    
    return strM;
}


3、什么是runtime
大多数情况下,运行时系统仅在幕后自动工作,主要用于编写和编译Objective-C源程序
程序调用之间的所有东西都是runtime
使用clang 反编译C++看一眼。


4、视频播放常用监听通知事件
状态变化
MPMoviePlayerPlaybackStateDidChangeNotification
播放结束
MPMoviePlayerPlaybackDidFinishNotification
退出全屏
MPMoviePlayerDidExitFullscreenNotification
截屏完成
MPMoviePlayerThumbnailImageRequestDidFinishNotification


截屏方法
-requestThumbnailImagesAtTimes:timeOption:


5、网络访问常用代码格式
NSURL *url = nil;
    NSURLRequest *requst = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:10.0f];
    // 新建一条线程,连接到网络,并等待返回数据
    [NSURLConnection sendAsynchronousRequest:requst queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
       
        // data就是从网络返回的数据
        // 对data处理
        // 重新回到主线程工作
        dispatch_async(dispatch_get_main_queue(), ^{
            // 更新UI
        });
    }];


6、Oc runtime
Objective-C runtime是一个实现Objective-C语言的C库。对象可以用C语言中的结构体表示,而方法(methods)可以用C函数实现。事实上,他们 差不多也是这么干了,另外再加上了一些额外的特性。这些结构体和函数被runtime函数封装后,Objective-C程序员可以在程序运行时创建,检 查,修改类,对象和它们的方法。


7、HTTP HEAD方法
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:kTimeout];
request.HTTPMethod = @"HEAD";
[NSURLConnection sendAsynchronousRequest:request queue:self.myQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    NSLog(@"%@", response);
    NSLog(@"---------------");
    NSLog(@"%@", data);
}];
运行测试代码可以发现,HEAD方法只是返回资源信息,而不会返回数据体
应用场景:
获取资源Mimetype
获取资源文件大小,用于端点续传或多线程下载


8、使用块代码获取网络资源大小的方法
- (void)fileSizeWithURL:(NSURL *)url completion:(void (^)(long long contentLength))completion
{
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:kTimeout];
    request.HTTPMethod = @"HEAD"; 
    NSURLResponse *response = nil;
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];
    
    completion(response.expectedContentLength);
}


9、确定每次下载数据包的伪代码实现
- (void)downloadFileWithURL:(NSURL *)url
{
    [self fileSizeWithURL:url completion:^(long long contentLength) {
        NSLog(@"文件总大小:%lld", contentLength);        
        // 根据大小下载文件
               while (contentLength > kDownloadBytes) {
            NSLog(@"每次下载长度:%lld", (long long)kDownloadBytes);
            contentLength -= kDownloadBytes;
        }
        NSLog(@"最后下载字节数:%lld", contentLength);
    }];
}


10、HTTP Range的示例
通过设置Range可以指定每次从网路下载数据包的大小
Range示例
bytes=0-499 从0到499的头500个字节
bytes=500-999 从500到999的第二个500字节
bytes=500- 从500字节以后的所有字节


bytes=-500 最后500个字节
bytes=500-599,800-899 同时指定几个范围
Range小结
- 用于分隔
前面的数字表示起始字节数
后面的数组表示截止字节数,没有表示到末尾
, 用于分组,可以一次指定多个Range,不过很少用


11、分段Range代码实现
long long fromBytes = 0;
long long toBytes = 0;
while (contentLength > kDownloadBytes) {
    toBytes = fromBytes + kDownloadBytes - 1;
    NSString *range = [NSString stringWithFormat:@"bytes=%lld-%lld", fromBytes, toBytes];
    NSLog(@"range %@", range);
    fromBytes += kDownloadBytes;
    contentLength -= kDownloadBytes;
}
fromBytes = fromBytes + contentLength - 1;
NSString *range = [NSString stringWithFormat:@"bytes=%lld-%lld", fromBytes, toBytes];
NSLog(@"range %@", range);


12、分段下载文件
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:kTimeout];
NSString *range = [NSString stringWithFormat:@"bytes=%lld-%lld", from, end];
[request setValue:range forHTTPHeaderField:@"Range"];


NSURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];
    
NSLog(@"%@-%@-%ld", range, response, (unsigned long)data.length);


提示:
如果GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是200(OK)


13、将数据写入文件
// 打开缓存文件
NSFileHandle *fp = [NSFileHandle fileHandleForWritingAtPath:self.cachePath];
// 如果文件不存在,直接写入数据
if (!fp) {
    [data writeToFile:self.cachePath atomically:YES];
} else {
    // 移动到文件末尾
    [fp seekToEndOfFile];
    // 将数据文件追加到文件末尾
    [fp writeData:data];
    // 关闭文件句柄
    [fp closeFile];
}


14、检查文件大小
// 判断文件是否存在
if ([[NSFileManager defaultManager] fileExistsAtPath:self.cachePath]) {
    NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:self.cachePath error:NULL];
    return [dict[NSFileSize] longLongValue];
} else {
    return 0;
}


提示:由于数据是追加的,为了避免重复从网络下载文件,在下载之前
判断缓存路径中文件是否已经存在
如果存在检查文件大小
如果文件大小与网络资源大小一致,则不再下载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值