Xcode 4.6用于游戏中心身份验证的ARC警告

时间:2013-01-30 22:31:19

标签: ios xcode automatic-ref-counting game-center xcode4.6

这是一个 new 编译器警告,只有在我将XCode更新为4.6时才出现。我的代码直接取自Apple的文档(这是我的iOS 6代码btw)。

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];

localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
    [self setLastError:error];
    if(localPlayer.authenticated){

警告 - 捕获' localPlayer'该块中的强烈可能导致保留周期

2 个答案:

答案 0 :(得分:25)

问题是localPlayer对象保持对自身的强引用 - 当localPlayer被“捕获”以在authenticateHandler块中使用时,它被保留(当在块中引用objective-c对象时,编译器在ARC电话为您保留)。现在,即使对localPlayer的所有其他引用都不再存在,它仍将保留计数为1,因此永远不会释放内存。这就是编译器给你一个警告的原因。

请参考弱引用,例如:

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];

__weak GKLocalPlayer *blockLocalPlayer = localPlayer;
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
    [self setLastError:error];
    if (blockLocalPlayer.authenticated) {
        ...

鉴于authenticateHandler和localPlayer的生命周期紧密相关(即当localPlayer被解除分配时,authenticateHandler也是如此),因此不需要在authenticateHandler中维护强引用。使用Xcode 4.6,这不再生成您提到的警告。

答案 1 :(得分:1)

编译器只是帮助你解决已经存在问题的代码,它之前并不知道。

您可以在此处阅读有关保留周期的信息:http://www.cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html

基本上你只需要将代码更改为:

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];

__weak MyViewController *blockSelf = self;
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
    [blockSelf setLastError:error];
    if(localPlayer.authenticated){