“[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]”使得 UI 无响应
"[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]" makes the UI non response
在 UIViewController
viewDidAppear
事件中,我想从网络服务中获取一些数据。代码如下:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSArray *arr = [self getCarList];
}
- (NSArray *)getCarList
{
if (!carList) {
ARequset *req = [[ARequset alloc] init];
[NetService sendRequest:req respClass:[Resp class] success:^(BaseResponse *response)
{
//after finished
self.requestFinished = YES;
} fail:^(NSInteger errcode, NSString *errmsg) {
self.requestFinished = YES;
}];
while (!self.requestFinished) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}
return carList;
}
当运行进入[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
时,请求成功块将不会执行,UI变为无响应。
但如果我像这样更改 - (void)viewDidAppear:(BOOL)animated
,一切顺利。
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self performSelector:@selector(getCarList) withObject:self afterDelay:1];
}
不要使用那种语法
NetService
请求异步工作,传递请求结果
在块中。您必须处理 BaseResponse
对象并更新您的 UI 或任何您想对数据执行的操作。
轮询是个坏习惯,会不必要地消耗系统资源。
除此之外,您还告诉当前 运行ning 运行UIApplication 循环到 运行 阻止它。
做这样的事情
- (void)getCarList
{
if (!carList) {
ARequset *req = [[ARequset alloc] init];
[NetService sendRequest:req respClass:[Resp class] success:^(BaseResponse *response)
{
//after finished
self.carList = [self doSomethingWithTheResponse:response];
dispatch_async(dispatch_get_main_queue(), ^(void) {
// Update UI
});
} fail:^(NSInteger errcode, NSString *errmsg) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
// show alert
});
}];
}
}
}
编辑: 或者使用类似委托的模式来处理异步行为。
代替同步方法
- (void)methodToGetCarList
{
NSArray *cars = [self getCarList];
[self doSomethingWithCars:cars];
}
使用这个
- (void)methodToGetCarListAsynchronously
{
[self getCarList];
}
和委托方法
- (void)didReceiveCars:(NSArray *)cars errorMessage:(NSString *)error
{
if (error) {
// do error handling
} else {
[self doSomethingWithCars:cars];
}
}
getCarList
方法看起来像
- (void)getCarList
{
if (!carList) {
ARequset *req = [[ARequset alloc] init];
[NetService sendRequest:req respClass:[Resp class] success:^(BaseResponse *response)
{
//after finished
self.carList = [self doSomethingWithTheResponse:response];
[self didReceiveCars:self.carList errorMessage:nil];
} fail:^(NSInteger errcode, NSString *errmsg) {
[self didReceiveCars:nil errorMessage:errmsg];
}];
}
} else {
[self didReceiveCars:self.carList errorMessage:nil];
}
}
代码不考虑在后台线程中响应 returns 的潜在问题。
在 UIViewController
viewDidAppear
事件中,我想从网络服务中获取一些数据。代码如下:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSArray *arr = [self getCarList];
}
- (NSArray *)getCarList
{
if (!carList) {
ARequset *req = [[ARequset alloc] init];
[NetService sendRequest:req respClass:[Resp class] success:^(BaseResponse *response)
{
//after finished
self.requestFinished = YES;
} fail:^(NSInteger errcode, NSString *errmsg) {
self.requestFinished = YES;
}];
while (!self.requestFinished) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}
return carList;
}
当运行进入[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
时,请求成功块将不会执行,UI变为无响应。
但如果我像这样更改 - (void)viewDidAppear:(BOOL)animated
,一切顺利。
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self performSelector:@selector(getCarList) withObject:self afterDelay:1];
}
不要使用那种语法
NetService
请求异步工作,传递请求结果
在块中。您必须处理 BaseResponse
对象并更新您的 UI 或任何您想对数据执行的操作。
轮询是个坏习惯,会不必要地消耗系统资源。
除此之外,您还告诉当前 运行ning 运行UIApplication 循环到 运行 阻止它。
做这样的事情
- (void)getCarList
{
if (!carList) {
ARequset *req = [[ARequset alloc] init];
[NetService sendRequest:req respClass:[Resp class] success:^(BaseResponse *response)
{
//after finished
self.carList = [self doSomethingWithTheResponse:response];
dispatch_async(dispatch_get_main_queue(), ^(void) {
// Update UI
});
} fail:^(NSInteger errcode, NSString *errmsg) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
// show alert
});
}];
}
}
}
编辑: 或者使用类似委托的模式来处理异步行为。
代替同步方法
- (void)methodToGetCarList
{
NSArray *cars = [self getCarList];
[self doSomethingWithCars:cars];
}
使用这个
- (void)methodToGetCarListAsynchronously
{
[self getCarList];
}
和委托方法
- (void)didReceiveCars:(NSArray *)cars errorMessage:(NSString *)error
{
if (error) {
// do error handling
} else {
[self doSomethingWithCars:cars];
}
}
getCarList
方法看起来像
- (void)getCarList
{
if (!carList) {
ARequset *req = [[ARequset alloc] init];
[NetService sendRequest:req respClass:[Resp class] success:^(BaseResponse *response)
{
//after finished
self.carList = [self doSomethingWithTheResponse:response];
[self didReceiveCars:self.carList errorMessage:nil];
} fail:^(NSInteger errcode, NSString *errmsg) {
[self didReceiveCars:nil errorMessage:errmsg];
}];
}
} else {
[self didReceiveCars:self.carList errorMessage:nil];
}
}
代码不考虑在后台线程中响应 returns 的潜在问题。