将NSTextField指针传递给IOUSBInterfaceInterface182回调

时间:2013-04-08 22:11:19

标签: cocoa callback usb

我正在从USB打印机进行异步读取。阅读工作正常。我的麻烦是从回调中更新NSTextField。

-(IBAction)printTest:(id)sender
{
    // Setup... then:

    NSLog(@"starting async read: %@", _printerOutput);
    NSLog(@"_printerOutput pointer = %p", _printerOutput);

    result = (*interface)->ReadPipeAsyncTO(interface,
                                           1,
                                           readBuffer,
                                           numBytesRead,
                                           500,
                                           1000,
                                           USBDeviceReadCompletionCallback,
                                           &(_printerOutput)
                                           );

回调定义为:

void USBDeviceReadCompletionCallback(void *refCon, IOReturn result, void *messageArg)
{
    NSTextField *printerOutput = (__bridge NSTextField *) messageArg;
    NSLog(@"_printerOutput pointer = %p", printerOutput);
}

指针在回调内部时会丢失其值。

starting async read: <NSTextField: 0x10221dc60>
_printerOutput pointer = 0x10221dc60
_printerOutput pointer = 0x0

我曾在许多地方试图模仿传递指针的不同方法。只有一种正确的方法。 :)

主题的另一个变体:(__ bridge void *)(_ printerOutput)。这也不起作用。

我知道回调的类型为IOAsyncCallback1。

其他注意事项:     http://www.google.com/search?client=safari&rls=en&q=another+usb+notification+example&ie=UTF-8&oe=UTF-8updating UI from a C function in a thread

1 个答案:

答案 0 :(得分:0)

我认为_printerOutputNSTextField*

首先,为什么要将NSTextField**传递给回调? (注意你传递给ReadPipeAsyncTO的最后一个参数中的&符号。)

其次,我会使用敏感代码避免使用ARC,这只是一种预防措施。

第三,from what I seeReadPipeAsyncTO的最后一个参数称为refcon。将回调的第一个参数称为refCon是巧合吗?请注意,您尝试从messageArg获取文本字段,而不是refCon


延伸我的第三点......

  1. ReadPipeAsyncTO有一个名为refcon的参数。这是最后一个参数
  2. 请在那里通过_printerOutput。不是指向_printerOutput的指针(不通过&(_printerOutput)) - _printerOutput已经是指针。
  3. 现在终于。查看回调的第一个参数。它被称为refcon。事实上 - 让我们看看Apple docs对此回调的评价:
  4.   

    REFCON

         

    refcon传入原始I / O请求

    我的结论是你的代码应该是:

    void USBDeviceReadCompletionCallback(void *refCon, IOReturn result, void *messageArg)
    {
        NSTextField *printerOutput = (__bridge NSTextField *) refCon; // <=== the change is here
        NSLog(@"_printerOutput pointer = %p", printerOutput);
    }
    

    请你试试这个吗?我觉得你没有尝试过这个。

    小但可能很重要的题外话:是否是其他一些对象,如果你没有使用ARC,我建议在将_printerOutput变量传递给ReadPipeAsyncTO时将其保留,并将其释放回调。

    但是,由于文本字段应该具有应用程序的生命周期,因此可能没有必要这样做。

    ARC可能会失去对指针后面对象的需求的跟踪,一旦它被传递到C代码中,但它没关系,因为指针仍然存储在printerOutput属性中。此外,一旦指针在C代码中,没有任何东西可以“跟随它”和“重置它”。

    理解和解释概念时的困惑正是我说“避免使用敏感代码的ARC”的原因。 : - )