这不是原始代码(我在尝试简化调试时将其剥离),但它确实显示了问题所在。从表面上看,很简单:
- (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;
当我在调试器(ToI ToI)中逐步通过测试方法时
浅谈NSLO的命中
(这甚至不涉及TOI),所有的TOI成员值都突然变为零。这不会发生在拷贝(NetoTi)上。如果我通过引用传递结构,则不会发生这种情况。如果将testmethod调用直接替换为方法体(即,如果我在本地运行这些行而不是调用方法),则不会发生这种情况。如果我将to i参数类型更改为一个包含两个int成员的虚拟结构(在调用之前创建),则不会发生这种情况。
值得指出的是,testmethod只能从自身内部调用
类,调用方刚刚从nsmutabledictionary(通过取消对nsvalue的装箱)中提取结构。但考虑到(a)结构是
通过值传递到这里的方法,以及(b)在输入它的成员时传递的值,如图所示
到了调试程序都如预期的那样,我不认为这会导致问题。结构中的两个对象指针也有棘手的问题,但是在其他上下文中,它们是OK的,它们在调试器中签入到方法中,所以我不认为我错过了基本的保留。
我想我会遇到某种堆或堆栈损坏,但我不知道是怎么回事,也不知道为什么。I_m是Objective-C的新成员,之前曾在
垃圾收集环境,所以我的内存管理经验有限。我完全有可能错过了一些显而易见的痛苦经历。
我希望有人会告诉我把touchdata改为对象类型,事实上我可能会这样做。我也有一些经过测试的解决方法,即要么使用副本,要么通过引用传递结构,但我真的想知道这里发生了什么。