If I define an Objective-C id
, in a struct
in a header file:
struct MyStruct {
id field;
};
struct MyStruct *_Nonnull myFunction(void);
Then I #include
this header into the bridging header then attempt to use myFunction()
from the Swift side, it will return OpaquePointer
. If I attempt to return MyStruct
directly, it will error saying myFunction
is not defined. This only occurs if MyStruct
contains an Objective-C id
.
What is strange is if I declare a normal variable of type id
, it can be ported to Swift just fine.
Why does Swift refuse structs containing Objective-C id
s and what should I do to circumvent this?
CodePudding user response:
Swift can't handle strong references in structs. It can't insert the required retains/releases.
You need to tell Swift it doesn't have to by marking the field __unsafe_unretained
:
struct MyStruct {
__unsafe_unretained id field;
};
With that, it will be imported normally, but field
will be Unmanaged
, which means you'll need to handle memory management yourself as needed.
Note that if this code is also called from ObjC, then this will change its memory management there, too. As discussed in the thread, you may need to check for the __swift__
define to check what language is compiling this header.