面试题答案
一键面试实现思路
- 设置流量限制:定义一个最大流量阈值,例如每秒允许发送的最大字节数。
- 记录流量:使用一个变量记录已发送的数据量。
- 定时器:使用NSTimer或GCD的dispatch_source创建一个定时器,定时(例如每秒)检查已发送的数据量是否超过阈值。
- 控制请求:如果超过阈值,暂停发送新的请求;如果未超过,则继续发送请求。
关键代码示例
- 使用NSTimer实现:
#import <UIKit/UIKit.h>
@interface NetworkTrafficController : NSObject
@property (nonatomic, assign) NSInteger totalSentBytes;
@property (nonatomic, assign) NSInteger maxBytesPerSecond;
@property (nonatomic, strong) NSTimer *trafficTimer;
- (void)startTrafficControl;
- (void)sendData:(NSData *)data;
@end
@implementation NetworkTrafficController
- (instancetype)init {
self = [super init];
if (self) {
_totalSentBytes = 0;
_maxBytesPerSecond = 1024 * 1024; // 1MB per second as an example
}
return self;
}
- (void)startTrafficControl {
self.trafficTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(resetTrafficCounter) userInfo:nil repeats:YES];
}
- (void)resetTrafficCounter {
self.totalSentBytes = 0;
}
- (void)sendData:(NSData *)data {
if (self.totalSentBytes + data.length <= self.maxBytesPerSecond) {
self.totalSentBytes += data.length;
// 实际发送数据的逻辑,例如使用NSURLSession发送请求
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"your-url"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 处理响应
}];
[task resume];
} else {
// 流量超过限制,处理方式可以是将请求加入队列稍后发送
NSLog(@"Traffic limit exceeded, cannot send data now.");
}
}
@end
- 使用GCD实现:
#import <UIKit/UIKit.h>
@interface NetworkTrafficController : NSObject
@property (nonatomic, assign) NSInteger totalSentBytes;
@property (nonatomic, assign) NSInteger maxBytesPerSecond;
@property (nonatomic, strong) dispatch_source_t trafficTimer;
- (void)startTrafficControl;
- (void)sendData:(NSData *)data;
@end
@implementation NetworkTrafficController
- (instancetype)init {
self = [super init];
if (self) {
_totalSentBytes = 0;
_maxBytesPerSecond = 1024 * 1024; // 1MB per second as an example
}
return self;
}
- (void)startTrafficControl {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
self.trafficTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(self.trafficTimer, dispatch_time(DISPATCH_TIME_NOW, 0), 1.0 * NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(self.trafficTimer, ^{
self.totalSentBytes = 0;
});
dispatch_resume(self.trafficTimer);
}
- (void)sendData:(NSData *)data {
if (self.totalSentBytes + data.length <= self.maxBytesPerSecond) {
self.totalSentBytes += data.length;
// 实际发送数据的逻辑,例如使用NSURLSession发送请求
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"your-url"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 处理响应
}];
[task resume];
} else {
// 流量超过限制,处理方式可以是将请求加入队列稍后发送
NSLog(@"Traffic limit exceeded, cannot send data now.");
}
}
@end
在实际使用中,可以创建NetworkTrafficController
的实例,调用startTrafficControl
方法开始流量控制,然后在需要发送数据的地方调用sendData:
方法。