gpt4 book ai didi

ios - 永远不要退出while循环

转载 作者:行者123 更新时间:2023-12-01 17:22:53 25 4
gpt4 key购买 nike

我有一个方法需要等待另一种方法完成从数据存储中加载一些对象。所以我正在使用这样的while循环:

-(void) findAGoodCar {
[self.indicator startAnimating];

while(appDelegate.availableCars == nil || [appDelegate.availableCars count] < 1) {
sleep(0.01);
}

// do some stuff
}

当这开始工作时,另一个用于装载汽车的过程已经开始。

现在,指示器永远不会开始动画。对象的加载永远不会完成。循环永远不会结束。为什么?

编辑:这是我的 loadCars 方法。应用启动时从 appDelegate 调用,从 (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions并且正在异步查询 Parse.com 的云:
+(void) loadCars {
PFQuery *query = [PFQuery queryWithClassName:kCarObjectKey];
[query whereKey:kActiveKey equalTo:[NSNumber numberWithInteger:kActiveNumber]];
NSSortDescriptor *sortByPrice = [[NSSortDescriptor alloc] initWithKey:kPriceKey ascending:YES];
[query orderBySortDescriptors:[NSArray arrayWithObjects:sortByPrice, nil]];

[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if(!error) {
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
appDelegate.availableCars = objects;
} else {
NSLog(@"Error in loadCars %@", error.localizedDescription);
}
}];
}

最佳答案

这是更新的帖子,因为真正作者的问题不是“无限循环”。

使用解析

Parse 提供了两种获取/向其服务器发送数据的方式:

  • 同步
  • 异步

  • 同步

    同步方法的缺点很明显——它会阻塞 UI 线程并且用户会看到无响应的 UI。

    那为什么要引入那组方法呢?

    当您在不知道结果的情况下无法继续工作时,您的应用程序登录中存在某些情况。在这种情况下,您必须使用同步方法。

    异步

    异步方法不会阻止 UI。但这需要对过程有更深入的了解。

    当然,您可以使用这样的循环:
    while(appDelegate.availableCars == nil || [appDelegate.availableCars count] < 1) {
    sleep(0.01);
    }

    这种方法会给你结果,但是你阻塞了一个 UI 线程。使用这种方法进行异步操作是不好的做法。您应该考虑使用 block 来处理异步请求。

    应用架构

    这是我对应用程序架构的看法。
    我更喜欢隔离所有代码,将 Parse(和其他 API)使用到单独的类中。
    所以我做了一个类,并使其成为单例

    ParseClient.h 文件:
    @interface ParseClient : NSObject
    // singleton
    + (instancetype) sharedInstance;
    @end

    ParseClient.m 文件:
    @implementation ParseClient
    + (instancetype) sharedInstance {
    static ParseClient *sharedInstace = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    sharedInstace = [[ParseClient alloc] init];
    });

    return sharedInstace;
    }
    @end

    所以现在您可以访问整个应用程序中的解析对象。现在您可以向此类添加所需的功能。您可以添加缓存(例如,将数组存储为实例变量)并制定自己的缓存策略。

    例如,您可以将以下函数添加到 ParseClient:
    - (void) loadCarsWithCompletionBlock:(void (^)(NSArray *objects, NSError *error))completionBlock {
    PFQuery *query = [PFQuery queryWithClassName:kCarObjectKey];
    [query whereKey:kActiveKey equalTo:[NSNumber numberWithInteger:kActiveNumber]];
    NSSortDescriptor *sortByPrice = [[NSSortDescriptor alloc] initWithKey:kPriceKey ascending:YES];
    [query orderBySortDescriptors:[NSArray arrayWithObjects:sortByPrice, nil]];

    [query findObjectsInBackgroundWithBlock:completionBlock];
    }

    并在您的应用程序中的任何位置调用它
    - (void) foo {
    ...
    [[ParseClient sharedInstance] loadCarsWithCompletionBlock:^(NSArray *objects, NSError *error){
    // you have array of cars here
    }];
    ...
    }

    关于ios - 永远不要退出while循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22295926/

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