将我的项目转换为ARC,但是由于以下错误“无法调用pthread_create的匹配函数”,它说不能。以下是它所涉及的代码,具体发生在以pthread create
开头的行上。我怎样才能解决这个问题?它还在错误下方的侧边栏中显示Candidate function not viable: no known conversion from 'NSString *' to 'void * _Nullable' for 4th argument
。
我已经切断了剩下的功能,但如果有必要可以提供更多细节。
void World::loadWorld(std::string name)
{
if(doneLoading==0)
{
doneLoading=1;
Resources::getResources->stopMenuTune();
if(LOW_MEM_DEVICE)
{
menu->deactivate();
Resources::getResources->unloadMenuTextures();
terrain->allocateMemory();
terrain->loadTerrain(name,TRUE);
doneLoading=2;
hud->fade_out=1;
}
else
{
terrain->allocateMemory();
pthread_t foo;
pthread_create(&foo,NULL,loadWorldThread, nsstring(name));
}
}
答案 0 :(得分:0)
由于您的错误消息指示pthread_create
的第4个参数属于void *
类型。在ARC下,您不能简单地将Obj-C对象引用作为void *
传递,因为ARC一旦存储在C(++)指针变量中就无法跟踪引用,因此无法管理对象&# 39;记忆。
对于必须将Obj-C引用传递到C(++)世界的情况,可以使用 bridge cast 来告知ARC应如何管理内存。但是在你的情况下有更好的方法,只需传递C ++指针name
,而不创建NSString
。如果loadWorldThread
期望std::string
无论如何都要做正确的事情。如果它需要NSString *
,那么:
修改它以获取std::string
并对其中的NSString *
进行任何必要的转换;或
编写一个小的中间函数,它接受std::string
,从中产生NSString *
,然后调用loadWorldThread
。将此新功能传递给pthread_create
。
执行上述任一操作可避免在pthread_create
调用中使用桥接强制转换将Obj-C引用移入C(++)世界并移出ARC控件;和loadWorldThread
中的另一个桥梁(或上面的中间函数)将其移回Obj-C世界并进入ARC控制。
<强>附录强>
扩展最后一段,因为方法似乎更适合您的情况。首先,你的代码是假设:
nsstring(name)
取值std::string
的值并返回NSString
类型的值,如果不是,则查找如何进行此转换。
在上面的表达式之后,您可以在ARC控件下引用NSString
。你不能简单地将这样的引用传递给void *
,你必须先将它从ARC的控件中取出并对其内存管理负责(但不会很久,你会看到)。您可以将NSString *
桥接到CFStringRef
:
CFStringRef cfName = (__bridge_retain CFStringRef)nsstring(name);
现在,您可以将cfName
作为CFString
的引用传递给void *
。
现在在loadWorldThread
;应声明为void *
,如void loadWorldThread(void *arg) { ... }
;你需要将你的CFStringRef
桥接到NSString *
并将其内存管理责任交给ARC:
NSString *nsName = (__bridge_transfer NSString *)arg;
以上是通过匿名引用(void *
)传递ARC控制引用的标准模式。
(注意:以上内容使用CFStringRef
表明您传递的是对手动管理的CFString
的引用,您可以直接转换为void *
并返回再次,确实你会注意到,当退回arg
时,没有首先投射到CFStringRef
以证明这一点。)
HTH