没有用于调用pthread_create Objective-C ARC转换的匹配函数

时间:2018-02-12 15:45:16

标签: objective-c memory-management automatic-ref-counting

将我的项目转换为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));
    }
}

1 个答案:

答案 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