在iOS中使用C函数中的ARC取消引用指针
我正在使用The Amazing Audio Engine来处理在iOS应用程序中同步的回放。在iOS中使用C函数中的ARC取消引用指针
该框架要求您使用C函数作为在音频线程上调用的回调函数(playbackTimingReceiver)。然后您需要使用传递处理程序(pageTurnHandler)的C函数(AEAudioControllerSendAsynchronousMessageToMainThread)再次向主线程发送消息。
我没有过多的C语言工作经验,但据我所知,我在需要解除引用的消息中传递一个指针。
,我可以用线顺利实现:
PlaybackManager* receiver = *((PlaybackManager**)userInfo);
但是,只有当我把ARC关闭该项目使用了-fno-objc弧标志的项目目标编译源该文件。
对我的问题,是否有可能实现这与ARC打开?如果是的话,什么是正确的语法?
相关代码段:
#pragma mark - Audio Timing Callback
-(AEAudioControllerTimingCallback)timingReceiverCallback
{
return playbackTimingReceiver;
}
static void playbackTimingReceiver(PlaybackManager* receiver,
AEAudioController *audioController,
const AudioTimeStamp *time,
UInt32 const frames,
AEAudioTimingContext context)
{
receiver->_hostTime = getUptimeInMilliseconds(time->mHostTime);
AEAudioControllerSendAsynchronousMessageToMainThread(audioController,
pageTurnHandler,
&audioController,
sizeof(id));
}
static void pageTurnHandler(AEAudioController *audioController, void *userInfo, int userInfoLength)
{
PlaybackManager* receiver = *((PlaybackManager**)userInfo);
NSLog(@"Receiver:%@", receiver);
}
PlaybackManager * receiver = (__bridge_transfer id)*(void **)userInfo;
应该做的伎俩。这首先将userInfo
转换为指针指针,因为它包含原始对象指针的地址。取消引用以获取原始指针,并使用__bridge_transfer
和id
或PlaybackManager
类型的工作 - 告诉ARC,取消引用的值实际上是一个需要照顾的对象。
没有运行的代码,似乎有两个错误:
1)你是路过的audioController
内容时,它看起来像你的意思的receiver
内容传递 - 所以最后两个参数传递给AEAudioControllerSendAsynchronousMessageToMainThread
应该&receiver
& sizeof(PlaykbackManager *)
2)你需要一个桥梁投来获取对象引用背出
喜欢的东西:
static void playbackTimingReceiver(PlaybackManager* receiver,
AEAudioController *audioController,
const AudioTimeStamp *time,
UInt32 const frames,
AEAudioTimingContext context)
{
receiver->_hostTime = getUptimeInMilliseconds(time->mHostTime);
AEAudioControllerSendAsynchronousMessageToMainThread(audioController,
pageTurnHandler,
&receiver,
sizeof(PlaybackManager*));
}
static void pageTurnHandler(AEAudioController *audioController, void *userInfo, int userInfoLength)
{
PlaybackManager* receiver = (__bridge Playback *)*((PlaybackManager**)userInfo);
NSLog(@"Receiver:%@", receiver);
}
注意:将ARC控件世界中的对象引用传递到C世界时,您经常会转移所有权 - 因此ARC不会释放引用的对象 - 并在返回时将所有权转移回来 - 所以ARC恢复所有权管理。但由于AEAudioControllerSendAsynchronousMessageToMainThread
的性质,其中userInfo
通过地址传递并在内部复制 - 因此是大小参数,所以转移所有权更为经济。因此上面的代码没有。这意味着你必须确保任何对象receiver
通过让另一个所有者保持活动状态。
你可以告诉ARC存储的类型,你想:
PlaybackManager *audioBufferPlayer = *(__weak PlaybackManager **)userInfo;
只要确保在访问任何属性或调用任何方法之前做必要的零检查。
如何解引用void指针? –
它不是取消引用无效指针,而是取消引用指针指针。 'void **' –
谢谢你...停止了编译器的抱怨,但是在运行时我得到了错误的访问:线程1:EXE_BAD_ACCESS(code = 1,address = 0x30000008) – Brendt