为什么我的指针被改变了?

时间:2011-09-08 00:29:34

标签: iphone objective-c pointers properties cocos2d-iphone

长话短说,我正在开发一个简单的游戏,我有一个Game对象,可以跟踪当前的游戏状态,以及稍后有用/需要的一些其他内容。其中一个是对加载游戏的UIViewController的引用,它被简单地声明为对象的属性:

@interface Game : NSObject {
    //ivars
}

@property (nonatomic, retain) myViewController* viewController;

此属性的getter / setter是使用@synthesize viewController生成的,一切似乎都很好。

现在只有两条路径可以访问此属性,当游戏获胜时以及游戏丢失时。 “游戏迷失”的路径运作良好。 “游戏赢了”路径导致了一个奇怪的错误,其中viewController指针的值似乎被垃圾覆盖。

为了弄清楚发生了什么,我按照以下方式覆盖了吸气剂和固定剂:

- (myViewController*) viewController {
    NSLog(@"Getting");
    return viewController;
}

- (void) setViewController:(myViewController*)controller {
    NSLog(@"Setting");
    viewController = controller;
}

...并在里面设置断点(我知道我不保留视图控制器是我的setter,但这不是问题;视图控制器仍然在堆栈中,实际上不需要由{{保留1}})。这是我在GDB中得到的:

Game

所以在某些时候,指针的值已从//first call to setter po controller <myViewController: 0x9208130> //call to getter on the "game is lost" path (gdb) po viewController <myViewController: 0x9208130> //call to setter, starting a new game from the same view controller (gdb) po controller <myViewController: 0x9208130> //call to getter on the "game is lost" path (gdb) po viewController 0xbea2222c does not appear to point to a valid object. (gdb) print viewController $1 = (myViewController *) 0xbea2222c 更改为0x9208130,但我无法弄清楚在哪里。除了在游戏开始时对setter的调用之外,没有代码分配到0xbea2222c属性(或其支持ivar)。然而显然有些事情正在用“赢得比赛”的道路覆盖垃圾的价值。

这可能是缓冲区溢出问题吗?如果是这样,追踪它的好方法是什么?

修改

我添加了第二个指针(作为另一个类中的ivar),我在游戏开始时将其设置为viewController的值,并使用此指针进行“游戏赢了”路径。所以在我看来,有些东西正在破坏原始指针。但是,仍然不知道是什么。

2 个答案:

答案 0 :(得分:3)

你的二传手是错的。它应该是:

- (void) setViewController:(yeticonfettiViewController*)controller {
    NSLog(@"Setting");
    [viewController autorelease];
    viewController = [controller retain];
}

否则你永远不会保留控制器,它可能会被垃圾收集。

答案 1 :(得分:1)

看起来没有足够的数据来诊断您发布的信息中的问题。

如果你想进一步调试这个问题,我建议在指针ivar的内存中设置一个断点。这样,如果在您的二传手使用之外以某种方式更改,您将收到通知。

你可以通过在Game对象创建过程中的某个时刻断开并在Game对象的控制器ivar上选择“Watch Variable”来完成此任务。

或者,asksol有一个很好的例子,可以在Xcode外部以类似的方式使用gdb来回答另一个问题here