前段时间开发,碰到了一个问题,请求一个java接口,后台返回的数据原本应该是视频数据流,本来可以直接使用NSData接收就OK,但是出现了以前未曾遇到的dispatch_data_t,因为文件过大的缘故,返回了dispatch_data_t类型的数据。
安排一下:
创建一个NSData类型的类别:
.h
//
// NSData+PIOAdditions.h
// LuoJing
//
// Created by 陈志远 on 2020/11/12.
// Copyright © 2020 陈志远. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <dispatch/data.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSData (PIOAdditions)
+ (instancetype)dataWithDispatchData:(dispatch_data_t)data;
// returns a dispatch_data_t representation of this object.
// This does not copy the internal bytes
- (dispatch_data_t)copyDispatchData DISPATCH_RETURNS_RETAINED;
@end
NS_ASSUME_NONNULL_END
.m
//
// NSData+PIOAdditions.m
// LuoJing
//
// Created by 陈志远 on 2020/11/12.
// Copyright © 2020 陈志远. All rights reserved.
//
#import "NSData+PIOAdditions.h"
// A way to do copyless dispatch data if the dispatch_data_t has just one segment.
@interface _PIOMappedDispatchData : NSData
- (instancetype)initWithData:(dispatch_data_t)data;
@end
@implementation NSData (PIOAdditions)
+ (instancetype)dataWithDispatchData:(dispatch_data_t)data;
{
return [[_PIOMappedDispatchData alloc] initWithData:data];
}
- (dispatch_data_t)copyDispatchData;
{
// just incase we are mutable;
CFDataRef immutableSelf = CFBridgingRetain([self copy]);
return dispatch_data_create(self.bytes, self.length, dispatch_get_main_queue(), ^{
CFRelease(immutableSelf);
});
}
@end
@implementation _PIOMappedDispatchData {
dispatch_data_t _data;
NSUInteger _length;
const void *_bytes;
}
- (instancetype)initWithData:(dispatch_data_t)data;
{
const void *buffer;
size_t size = 0;
data = dispatch_data_create_map(data, &buffer, &size);
self = [super init];
if (self != nil) {
_bytes = buffer;
_length = size;
_data = data;
}
return self;
}
- (NSUInteger)length;
{
return _length;
}
- (const void *)bytes;
{
return _bytes;
}
- (dispatch_data_t)copyDispatchData;
{
return _data;
}
- (void)dealloc
{
if (_data != NULL) {
}
}
- (id)copy;
{
return [[_PIOMappedDispatchData alloc] initWithData:_data];
}
@end