块内部的变量赋值
variable assignment from inside of a block
我正在使用 Swift 中的 Objective-C。我几乎没有 objective-c 经验。我正在尝试使用 Apple 的示例访问游戏中心并检索前 10 名排行榜分数以在 Swift 中使用。但是,我坚持 objective-c 分配的基础知识,其中将检索到的分数数据传递回调用者。有人可以 post 提供如何处理此问题的代码示例吗?
- (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;
}
您的 return 值将是 nil
。这是因为 loadScoresWithCompletionHandler
是一个在后台线程中执行的异步方法,可能需要一些时间来下载数据。在块完成执行之前,执行到达 return temp
。为了保存scores
数据,可以在class.
中定义一个property
@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
}
然后将对此方法的调用作为回调处理程序传递给预期的排行榜请求。
使用块类似于 Javascript 中的编码。结果数据稍后到达——甚至在方法完成执行之后。所以你不能return数组。
loadScoresWithCompletionHandler: 之后缩进的所有内容都将在加载分数/之后/加载分数后发生。您将需要更新该代码块内的 UI。
您正在调用异步方法,因此您应该采用异步模式。现在最常见的约定是使用块(就像 Apple 提供的 loadScoresWithCompletionHandler
方法一样)。最重要的是,与其立即尝试 return NSArray
,不如提供您自己的 retrieveTopTenScores
方法一个将在请求完成时调用的块:
最简单的格式如下:
- (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 或模型对象,这很重要),那么您可能想要执行类似以下(但只需像上面那样称呼它):
- (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:^(NSArray *scores, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(scores, error);
});
}];
}
}
我正在使用 Swift 中的 Objective-C。我几乎没有 objective-c 经验。我正在尝试使用 Apple 的示例访问游戏中心并检索前 10 名排行榜分数以在 Swift 中使用。但是,我坚持 objective-c 分配的基础知识,其中将检索到的分数数据传递回调用者。有人可以 post 提供如何处理此问题的代码示例吗?
- (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;
}
您的 return 值将是 nil
。这是因为 loadScoresWithCompletionHandler
是一个在后台线程中执行的异步方法,可能需要一些时间来下载数据。在块完成执行之前,执行到达 return temp
。为了保存scores
数据,可以在class.
property
@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
}
然后将对此方法的调用作为回调处理程序传递给预期的排行榜请求。
使用块类似于 Javascript 中的编码。结果数据稍后到达——甚至在方法完成执行之后。所以你不能return数组。
loadScoresWithCompletionHandler: 之后缩进的所有内容都将在加载分数/之后/加载分数后发生。您将需要更新该代码块内的 UI。
您正在调用异步方法,因此您应该采用异步模式。现在最常见的约定是使用块(就像 Apple 提供的 loadScoresWithCompletionHandler
方法一样)。最重要的是,与其立即尝试 return NSArray
,不如提供您自己的 retrieveTopTenScores
方法一个将在请求完成时调用的块:
最简单的格式如下:
- (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 或模型对象,这很重要),那么您可能想要执行类似以下(但只需像上面那样称呼它):
- (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:^(NSArray *scores, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(scores, error);
});
}];
}
}