Home > Mobile >  Why can ids not be ported from Objective-C to Swift via struct?
Why can ids not be ported from Objective-C to Swift via struct?

Time:11-04

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 ids 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.

  • Related