- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在为 Metal API ( http://github.com/recp/cmtl) 开发 C 包装器/绑定(bind)。
我在 C header 中将 Objective-C 类型定义为 void,例如 typedef void MtDevice
.然后我将在 ObjC 函数中分配的对象转换为 void* 指针。然后将其转换回 ObjC 以调用 ObjC 函数。
这里是我的代码[s]:
ARC 样式:
MtDevice*
mtDeviceCreat() {
id<MTLDevice> mdevice;
mdevice = MTLCreateSystemDefaultDevice();
return (void *)CFBridgingRetain(mdevice);
}
MtCommandQueue*
mtCommandQueue(MtDevice *device) {
id<MTLDevice> mdevice;
id<MTLCommandQueue> mcmdQueue;
mdevice = (__bridge id<MTLDevice>)device;
mcmdQueue = [mdevice newCommandQueue];
return (void *)CFBridgingRetain(mcmdQueue);
}
ARC 禁用:
MtDevice*
mtDeviceCreat() {
id<MTLDevice> mdevice;
mdevice = MTLCreateSystemDefaultDevice();
return [mdevice retain];
}
MtCommandQueue*
mtCommandQueue(MtDevice *device) {
id<MTLDevice> mdevice;
id<MTLCommandQueue> mcmdQueue;
mdevice = (__strong id<MTLDevice>)device;
mcmdQueue = [mdevice newCommandQueue];
return [mcmdQueue retain];
}
我正在考虑禁用 ARC,因此我将其转换为第二个版本。这里有几个问题:
newCommandQueue
之后和类似的功能我应该在返回之前保留对象吗?mdevice = (__strong id<MTLDevice>)device;
将 void* 转换为 ObjC 类型,但是这个呢:mdevice = device;
?编译器似乎没有提示。PS:我的 C 函数只是从 C 调用 ObjC 函数的包装器。我并没有尝试访问 C 函数中的 ObjC 类成员。
编辑:
发布代码:
void
mtRelease(void *obj) {
[(id)obj release];
}
编辑 2:
更新代码(禁用 ARC):
MtDevice*
mtDeviceCreat() {
return MTLCreateSystemDefaultDevice();
}
MtCommandQueue*
mtCommandQueue(MtDevice *device) {
return [(id<MTLDevice>)device newCommandQueue];
}
最佳答案
在这两种情况下,对 -retain
的调用是不正确的。 MTLCreateSystemDefaultDevice()
遵循 the Create Rule , 所以它已经为你保留了。您负责一次(自动)发布以平衡原始创作,并为您执行的每个 -retain
负责一次。
同样,-newCommandQueue
返回一个已保留且您最终必须释放的对象。 That's true of any method starting with "new" .
__strong
在禁用 ARC 时不执行任何操作。 mdevice = device;
没问题。
将 Objective-C 对象指针转换为 void*
并返回是“安全的”(除了类型安全的损失)。我建议您使用指向不透明结构类型的指针而不是 void*
,以保持类型安全。例如,typedef struct MtDevice *MtDeviceRef;
,其中从未定义 struct MtDevice
。这就是 Apple 定义自己的类型的方式,例如 CFStringRef
。
关于objective-c - 将 ObjC id<Protocol> 和类型对象转换为 C 指针 (void *) 然后将其转换回去是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51078135/
我可以从我的 mainActivity 转到我的 SoundActivity 类,这是一个菜单。但是,当我单击设备后退按钮时,它不会返回到我的 mainActivity 而只是关闭应用程序。我已将 f
我有一个很大的命名分支,有很多更改。其中一些更改是非破坏性的,因此我想首先选择这些特定文件,并尽快将其与默认文件合并。 (然后,破坏性更改也将合并。) 在Git中,我将创建另一个分支并压缩索引之外的所
我有一棵树: /--b1---b2 $a; git add $a; git commit -am $a; git tag $a; done git checkout -b b; for
我是一名优秀的程序员,十分优秀!