我有一个 Objective-C 方法,它创建一个指针,然后使用 performSelectorInBackground: 将它传递给一个新线程。问题是,我需要将指针的地址传递给线程,因为我想从线程中释放与其关联的内存。我遇到的问题是,当新线程启动时,调用方法结束,导致指针超出范围。如何在线程可以接收指针地址的地方保持足够长的时间?
如果我只是在主线程上调用“pointerTest”方法,这一切当然都有效。
这是我的代码:
-(void)pointerTest:(NSValue*)pointer
{
void **p = (void**)[pointer pointerValue];
fprintf(stderr,"p was %s\n",(char*)(*p)); //prints "Hello There!"
free(*p);
*p = NULL;
}
现在,在主线程上:
-(IBAction)doTest:(id)sender
{
char *str = "Hello There!";
void *p = malloc(strlen(str)+1);
strcpy(p, str);
//this works
//[self pointerTest:[NSValue valueWithPointer:&p]];
//this fails
[self performSelectorInBackground:@selector(pointerTest:) withObject:[NSValue valueWithPointer:&p]];
if(!p){
fprintf(stderr,"p was NULL!\n");
}else{
fprintf(stderr,"p was NOT NULL: %s\n",p);
}
}
更新:
这段代码表明,如果我不将指针传递给 pointerTest:,我无法从 pointerTest 中释放 p:
-(void)pointerTest:(NSValue*)pointer
{
void *p = (void*)[pointer pointerValue];
fprintf(stderr,"p was %s\n",(char*)p); //prints "Hello There!"
free(p);
fprintf(stderr,"p was %s\n",(char*)p); //STILL prints "Hello There!"
*p = NULL;
fprintf(stderr,"p was %s\n",(char*)p); //prints "(null)"
}
现在,在调用方法中:
//I pass p, NOT a pointer to p
[self pointerTest:[NSValue valueWithPointer:p]];
if(p){
//p is not NULL, and in fact I can print its value
fprintf(stderr,"p was NOT NULL: %s\n",p);
}
但是,如果我将指针传递给 p 而不是 p,我可以按预期从 pointerTest 中释放它的值:并且在从 pointerTest 返回时,调用方法中的 p 为 NULL。