我的应用程序中有多个位置显示从服务器返回的对象列表。我试图重新编写一些代码,因此只需要在一个地方而不是三个地方进行修改即可进行更新。
基本要点如下:
PFQuery *query = [PFQuery queryWithClassName:"MyClass"];
//query constraints
[query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
if( !error ) //Do stuff with objects;
else [self displayError:error];
}];
我为这个类设置了PFObject
子类,所以我有一个名为MyClass
的类。我试图在这个类上放一个类方法,返回一个包含查询结果的NSArray *
。但是,以下函数会引发一些错误:
+(NSArray *)getListOfMyClass {
PFQuery *query = [PFQuery queryWithClassName:"MyClass"];
//query constraints
[query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
if( !error ) return objects;
else [self displayError:error];
}];
}
此错误出现在函数的末尾:
Control may reach end of non-void block
此错误显示在return objects;
:Incompatible block pointer types sending 'NSArray * _Nullable (^)(NSArray * _Nullable __strong, NSError * _Nullable __strong)' to parameter of type 'PFQueryArrayResultBlock _Nullable' (aka 'void (^)(NSArray<PFGenericObject> * _Nullable __strong, NSError * _Nullable __strong)')
所以,我知道这个问题是由于这个查询的异步行为造成的。我需要从几个不同的地方调用这个查询,所以希望我可以调用单个函数,但现在我已经迷失了如何使这个效率高,而不是非常混乱。我有点倾向于只是排队三次,因为这就是我现在所做的事情,但我试图学习更好的做法。
有没有办法可以强制此函数等待返回,直到查询成功为止?或者传入发件人,然后触发传递结果的发件人的函数是否可以?我会在后者上工作,看看它是否有效,但即使这样看起来如此迂回。我想知道是否有一些显而易见的东西我不知道。
感谢您的帮助!
注意 - 我更喜欢Objective C答案,但如果需要,可以使用Swift答案。
答案 0 :(得分:1)
根据PFQuery.h
:
typedef void (^PFQueryArrayResultBlock)(NSArray<PFGenericObject> *_Nullable objects, NSError * _Nullable error);
findObjectsInBackgroundWithBlock
是一个没有返回任何内容的void块,所以很明显return语句会导致错误。
如果要检索数组,可以使用完成处理程序,如:
+(void)getListOfMyClassWithCompletionBlock:(void (^)(NSError *error, NSArray *objectArray))block {
PFQuery *query = [PFQuery queryWithClassName:"MyClass"];
//query constraints
[query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
if( !error ) block(nil, objects);
else block(error, nil); [self displayError:error];
}];
}
代码中的其他地方(其他类):
[YourClass getListOfMyClassWithCompletionBlock:^(NSError *error, NSArray *objectArray) {
if (!error) //update your UI with objectArray
}];