0

我正在从 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 类型的。

其他值得注意的 URL: http ://www.google.com/search?client=safari&rls=en&q=another+usb+notification+example&ie=UTF-8&oe=UTF-8并 从线程中的 C 函数更新 UI

4

1 回答 1

0

我想_printerOutput是一个NSTextField*

首先,您是否有特殊原因将 an 传递NSTextField**给回调?(请注意您传递给的最后一个参数中的与号ReadPipeAsyncTO。)

其次,作为预防措施,我会避免使用敏感代码的 ARC。

第三,据我所见,最后一个参数ReadPipeAsyncTO称为refcon。回调的第一个参数被调用是巧合refCon吗?请注意,您正在尝试从messageArg而不是获取文本字段refCon


继续我的第三点……</p>

  1. ReadPipeAsyncTO有一个名为refcon. 这是最后一个论点
  2. 请通过_printerOutput那里。Not a pointer to _printerOutput(do not pass &(_printerOutput)) --_printerOutput已经是一个指针。
  3. 现在终于。查看回调的第一个参数。它被称为refcon。事实上——让我们看看Apple 文档对这个回调是怎么说的:

参考

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,并在回调中释放它。

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

一旦将指针传递到 C 代码中,ARC 可能会忘记指针背后的对象是否需要存在,但这并不重要,因为指针仍存储在printerOutput属性中。此外,一旦指针在 C 代码中,没有什么可以“跟随它”和“重置它”。

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

于 2013-04-08T22:50:24.890 回答