gpt4 book ai didi

ios - "[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]"使UI无响应

转载 作者:行者123 更新时间:2023-11-28 19:45:25 24 4
gpt4 key购买 nike

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]];时,请求成功 block 不会执行,UI变为无响应。

但如果我像这样更改 - (void)viewDidAppear:(BOOL)animated,一切顺利。

 - (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self performSelector:@selector(getCarList) withObject:self afterDelay:1];
}

最佳答案

不要做那种语法

NetService请求异步工作,传递请求结果在 block 中。您必须处理 BaseResponse 对象并更新您的 UI 或任何您想对数据执行的操作。

轮询是一种坏习惯,会不必要地消耗系统资源。

除此之外,您还告诉当前正在运行的 UIApplication runloop 运行哪个阻止了它。

做这样的事情

- (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
});
}];
}
}
}

编辑:或者使用类似委托(delegate)的模式来处理异步行为。

代替同步方法

- (void)methodToGetCarList
{
NSArray *cars = [self getCarList];
[self doSomethingWithCars:cars];
}

使用这个

- (void)methodToGetCarListAsynchronously
{
[self getCarList];
}

和委托(delegate)方法

- (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];
}
}

如果响应在后台线程中返回,代码不会考虑潜在问题。

关于ios - "[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]"使UI无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32520649/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com