这不是原始代码(我试图简化调试时剥离了一些东西),但它确实显示了问题。在它面前,看起来很简单:为什么传值结构参数被破坏?
- (void) testMethod: (TouchData) toi {
TouchData newToi = toi;
NSString *test = @"test string";
NSLog(@"string: %@", test);
// in ‘real’ code I pass the struct back
// It’s void here for the simplest possible
// case
}
TouchData是一个结构,从而宣告:
typedef struct {
Entity *owner;
CGPoint startPos;
CGPoint latestPos;
CGPoint startOfStraightSwipePos;
NSTimeInterval startTime;
NSTimeInterval latestTime;
NSTimeInterval startOfStraightSwipeTime;
CGFloat latestSpeed;
NSMutableArray *gestures;
BOOL isOfInterest;
} TouchData;
当我通过TestMethod的在调试步骤(看TOI)上打的NSLog(甚至不涉及toi),所有toi成员值突然消失。这不会发生在副本(newToi)上。如果我通过引用传递结构,则不会发生这种情况。如果直接用方法体替换testMethod调用(即,如果我现场运行这些行而不是调用方法),则不会发生这种情况。如果我将toi参数类型更改为具有几个int成员的虚拟结构体(在调用之前创建),则不会发生这种情况。
可能值得指出的是,testMethod仅在其自己的 类中调用,并且调用方刚刚从NSMutableDictionary中提取了结构(通过拆开NSValue)。但考虑到(a)结构是 在这里通过值传递给方法,和(b)在入口处它的成员如 由调试器完全符合预期,我没有看到这可能导致问题。在结构中还有两个对象指针的棘手问题,但在其他上下文中,他们正在确定,并且在调试器中检查该方法的入口,所以我不认为我已经错过了基本保留。
我想我遇到了某种堆或堆栈腐败,但我不知道如何或为什么。我是Objective-C的新手,之前曾在 垃圾收集环境中工作,所以我的内存管理经验有限。我完全有可能错过了一些显而易见的事情。
我希望有人会告诉我让TouchData成为一种对象类型,事实上我可能会那样做。我也有一些测试过的解决方法,即。要么在副本上工作,要么在ref中传递结构。但我真的很想知道这里发生了什么。
在原始方法中,您的返回值是否损坏? – Ryan 2010-11-12 05:31:14
这是,我认为它一定是一个内存管理问题。但我很确定简化代码中发生的事情是不同的,正如Yuji在下面解释的那样。我已经将TouchData重新实现为一个类,它更直接地工作。 – Cris 2010-11-13 02:52:09