Ios 从块内部进行变量赋值
我用的是Swift的Objective-C。我几乎没有objective-c的经验。我正在尝试使用苹果的示例访问游戏中心,并检索排名前10的排行榜分数,以便在Swift中使用。然而,我坚持使用objective-c赋值的基础知识,即将检索到的分数数据传递回调用方。有人可以发布一个代码示例来说明如何处理这个问题吗Ios 从块内部进行变量赋值,ios,objective-c,Ios,Objective C,我用的是Swift的Objective-C。我几乎没有objective-c的经验。我正在尝试使用苹果的示例访问游戏中心,并检索排名前10的排行榜分数,以便在Swift中使用。然而,我坚持使用objective-c赋值的基础知识,即将检索到的分数数据传递回调用方。有人可以发布一个代码示例来说明如何处理这个问题吗 - (NSArray*) retrieveTopTenScores { GKLeaderboard *leaderboardRequest = [[GKLeaderboard a
- (NSArray*) retrieveTopTenScores
{
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
NSArray *temp = nil;
if (leaderboardRequest != nil)
{
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeToday;
leaderboardRequest.identifier = @"Appid";
leaderboardRequest.range = NSMakeRange(1,10);
[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
if (error != nil)
{
// Handle the error.
NSLog(@"error in score retrieval");
}
if (scores != nil)
{
temp = scores; //results to Variable is not assignable (missing __block type specifier)
}
}];
}
return temp;
}
您的返回值将为
nil
。这是因为loadScoresWithCompletionHandler
是一个异步方法,在后台线程中执行,下载数据可能需要时间。在块完成执行之前,执行到达返回温度。为了保存分数
数据,您可以在类中定义属性
@property (nonatomic,strong) NSArray *topTenScores;
然后可以在块内指定特性。如果要显示toptenscore,还可以从块内部对主线程进行函数调用来更新UI
[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error)
{
if (error != nil)
{
// Handle the error.
NSLog(@"error in score retrieval");
}
if (scores != nil)
{
self.topTenScores = score;
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI on the main thread.
});
}
}];
您的返回值将为
nil
。这是因为loadScoresWithCompletionHandler
是一个异步方法,在后台线程中执行,下载数据可能需要时间。在块完成执行之前,执行到达返回温度。为了保存分数
数据,您可以在类中定义属性
@property (nonatomic,strong) NSArray *topTenScores;
然后可以在块内指定特性。如果要显示toptenscore,还可以从块内部对主线程进行函数调用来更新UI
[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error)
{
if (error != nil)
{
// Handle the error.
NSLog(@"error in score retrieval");
}
if (scores != nil)
{
self.topTenScores = score;
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI on the main thread.
});
}
}];
最好是让主应用程序控制器实现处理排行榜接收的方法,例如:
- (void) handleResultsOfLeaderBoardRequest: (NSArray *) leaderboards error: (NSError *error) {
// store the list in an attribute or process otherwise
}
然后,您将调用此方法作为预期排行榜请求的回调处理程序。最好是让主应用程序控制器实现处理排行榜接收的方法,例如:
- (void) handleResultsOfLeaderBoardRequest: (NSArray *) leaderboards error: (NSError *error) {
// store the list in an attribute or process otherwise
}
然后将调用传递给此方法,作为预期排行榜请求的回调处理程序。使用块类似于在Javascript中编码。结果数据的到达时间较晚——即使在方法完成执行之后也是如此。因此无法返回数组
加载分数后缩进的所有内容将在加载分数后发生。您需要更新该代码块内的UI。使用代码块类似于在Javascript中编码。结果数据的到达时间较晚——即使在方法完成执行之后也是如此。因此无法返回数组
加载分数后缩进的所有内容将在加载分数后发生。您将需要更新该代码块内的UI。您正在调用异步方法,因此应该采用异步模式。现在最常见的约定是使用块(就像苹果提供的
loadScoresWithCompletionHandler
方法一样)。总之,不要试图立即返回NSArray
,而是提供您自己的retrieveoptenscores
方法一个在请求完成时调用的块:
最简单的格式副本如下所示:
- (void)retrieveTopTenScoresWithCompletionHandler:(void (^)(NSArray *scores, NSError *error))completionHandler
{
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
if (leaderboardRequest != nil) {
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeToday;
leaderboardRequest.identifier = @"Appid";
leaderboardRequest.range = NSMakeRange(1,10);
[leaderboardRequest loadScoresWithCompletionHandler:completionHandler];
}
}
你会这样称呼它:
[self retrieveTopTenScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
if (scores) {
// use scores array here
} else {
//do something with error here
NSLog(@"retrieveTopTenScoresWithCompletionHandler error: %@", error);
}
}];
// but do not try to use `scores` here, because the above runs asynchronously
// and thus, we don't have the scores by the time we get here
注意,如果希望在主队列上运行该完成块(这在更新UI或模型对象时非常重要),则可能需要执行以下操作(但只需像上面那样调用它):
您正在调用异步方法,所以应该采用异步模式。现在最常见的约定是使用块(就像苹果提供的
loadScoresWithCompletionHandler
方法一样)。总之,不要试图立即返回NSArray
,而是提供您自己的retrieveoptenscores
方法一个在请求完成时调用的块:
最简单的格式副本如下所示:
- (void)retrieveTopTenScoresWithCompletionHandler:(void (^)(NSArray *scores, NSError *error))completionHandler
{
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
if (leaderboardRequest != nil) {
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeToday;
leaderboardRequest.identifier = @"Appid";
leaderboardRequest.range = NSMakeRange(1,10);
[leaderboardRequest loadScoresWithCompletionHandler:completionHandler];
}
}
你会这样称呼它:
[self retrieveTopTenScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
if (scores) {
// use scores array here
} else {
//do something with error here
NSLog(@"retrieveTopTenScoresWithCompletionHandler error: %@", error);
}
}];
// but do not try to use `scores` here, because the above runs asynchronously
// and thus, we don't have the scores by the time we get here
注意,如果希望在主队列上运行该完成块(这在更新UI或模型对象时非常重要),则可能需要执行以下操作(但只需像上面那样调用它):
将其声明为
\u块NSArray*temp=nil
因此警告将消失,但返回值将为null,因为您的分数是在异步方法上加载的,因此,在您获得结果之前将执行return语句。测试是让您的主应用程序控制器实现一个处理结果接收的方法。例如,此设计存在一个基本问题,因为当此完成处理程序被称为temp时,已返回。temp仅在本地范围内,即在此方法内。我认为您应该将此方法签名更改为-(void)。阵列尚未准备好立即返回。然后继续,但将(此NSArray数据)设置为iVar或属性,然后触发另一个方法来通知返回的结果。将其声明为\u block NSArray*temp=nil
因此警告将消失,但返回值将为null,因为您的分数是在异步方法上加载的,因此,在您获得结果之前将执行return语句。测试是让您的主应用程序控制器实现一个处理结果接收的方法。例如,此设计存在一个基本问题,因为当此完成处理程序被称为temp时,已返回。temp仅在本地范围内,即在此方法内。我认为您应该将此方法签名更改为-(void)。阵列尚未准备好立即返回。然后按原样继续,但将(此NSArray数据)设置为iVar或属性,然后触发另一个方法来通知返回的结果..是的,我的注释与您键入的内容几乎相同+1否,RetrieveTopensCores
没有更新用户界面的业务。也有选择是否有一个clas