我有一个奇怪的问题。我在我的应用程序中使用来自 Apple 私有框架的方法。当我第一次调用它时,它起作用了。当我立即第二次调用它而没有任何中间内容时,它崩溃了。但是,如果我将 NSLog 放在两个调用之间,效果会非常好。所以我尝试删除 NSLog 并在它们之间放置 for-loops、sleep()、printf("...") 和 fprintf(stderr, "...") 以模拟 NSLog,但这没有帮助。我想知道该方法是如何知道我使用 NSLog 的?换句话说,NSLog 实际上做了什么来影响方法的行为?
非常感谢!
编辑:
我似乎解决了这个问题。我将在这里分享我的解决方案,希望它对某些人有用。
我正在使用 MultitouchSupport.framework 创建一个与多点触控相关的应用程序。我从http://aladino.dmi.unict.it/?a=multitouch复制了代码,并CFRelease
在循环末尾添加了一个。所以,基本上,我的主要方法是这样的:
int main(void) {
int i;
NSMutableArray* deviceList = (NSMutableArray*)MTDeviceCreateList(); //grab our device list
for(i = 0; i<[deviceList count]; i++) { //iterate available devices
MTRegisterContactFrameCallback([deviceList objectAtIndex:i], touchCallback); //assign callback for device
MTDeviceStart([deviceList objectAtIndex:i], 0); //start sending events
}
CFRelease((CFMutableArrayRef)deviceList);
printf("Ctrl-C to abort\n");
sleep(-1);
return 0;
}
运行一段时间后,会显示“程序接收信号:“EXC_BAD_ACCESS”。这是堆栈跟踪:
#0 0x7fff8795496e in ParsedMultitouchFrameRepInitialize
#1 0x7fff879565b1 in mt_HandleMultitouchFrame
#2 0x7fff87955a03 in mt_DequeueDataFromDriver
#3 0x7fff87955b29 in mt_DequeueMultitouchDataFromDriverThreadEntry
#4 0x7fff831b3456 in _pthread_start
#5 0x7fff831b3309 in thread_start
但是,如果我将 NSLog 放在 MTDeviceStart 下面,它不会崩溃。
我添加CFRelease((CFMutableArrayRef)deviceList)
到原始代码中的原因是我认为从名为 *Create* 或 *Copy* 的函数创建的对象应该由我们自己释放。但事实证明,如果我像原始代码一样删除它,即使不使用 NSLog,它也不会崩溃。
所以,也许是因为我发布deviceList
得太早了?但如果是这样,为什么 NSLog 似乎能够防止崩溃呢?