我有一个奇怪的问题。我在我的应用程序中使用Apple的私有框架中的方法。当我第一次打电话时,它有效。当我第二次立即呼叫它时,两者之间没有任何东西,它会崩溃。但是,如果我在两个调用之间放置NSLog,它可以很好地工作。所以我尝试删除NSLog并在它们之间放置for循环,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似乎能够防止崩溃?
答案 0 :(得分:2)
类似的东西:
static inline void NSLogMessageString(NSString *string){
NSString *date=[[NSDate date]
descriptionWithCalendarFormat:@"%Y-%m-%d %H:%M:%S.%F"
timeZone:nil locale:nil];
NSString *process=[[NSProcessInfo processInfo] processName];
NSLogFormat(@"%@ %@[%d:%lx] %@",date,process,NSPlatformProcessID(),NSPlatformThreadID(),string);
}
void NSLogv(NSString *format,va_list arguments) {
NSString *string=NSStringNewWithFormat(format,nil,arguments,NULL);
NSLogMessageString(string);
[string release];
}
void NSLog(NSString *format,...) {
va_list arguments;
va_start(arguments,format);
NSLogv(format,arguments);
}
感谢您提出这个问题大声笑,我想重写它,以便我可以添加调试变量,这意味着我可以在需要时关闭所有NSLogging调用。
答案 1 :(得分:1)
需要很长时间。我不知道为什么。它打印日期/时间,进程名称,进程ID,线程ID,以及(最后)您要求的字符串。我认为它还将日志消息发送到syslogd(Xcode或iPCU的控制台将多行NSLogs显示为单个条目;我忘记了哪个); IPC可能会有重大意义。
尝试使用syslog()(#import <syslog.h>
然后syslog(LOG_INFO, "Hello there!");
,如果它有效但没有输出,请尝试更改优先级(请参阅man 3 syslog
)。
答案 2 :(得分:1)
答案 3 :(得分:0)
这可能是内存管理的一个问题:也许是一个无关的版本。如果您发布回溯,则可能有助于跟踪问题。 (事实证明,我在Twitter上关注的人昨晚提到了这样的事情。)