When an API is marked with NS_REFINED_FOR_SWIFT
, it will be prefixed with two underscores (__
) when imported to Swift:
NS_REFINED_FOR_SWIFT
The generated interface looks like this:
__indexOfObject
Now you can replace the API with a more “Swifty” extension. In this case, we can use an optional return value, filtering out NSNotFound:
indexOfObjectInt?
In most cases you might want to restrict whether or not an argument to an Objective-C function could be nil
. This is done using _Nonnull
keyword, which qualifies any pointer or block reference:
void
doStuff(const void *const _Nonnull data, void (^_Nonnull completion)())
{
// complex asynchronous code
}
With that written, the compiler shall emit an error whenever we try to pass nil
to that function from our Swift code:
doStuff(
nil, // error: nil is not compatible with expected argument type 'UnsafeRawPointer' nil) // error: nil is not compatible with expected argument type '() -> Void'
The opposite of _Nonnull
is _Nullable
, which means that it is acceptable to pass nil
in this argument. _Nullable
is also the default; however, specifying it explicitly allows for more self-documented and future-proof code.
To further help the compiler with optimising your code, you also might want to specify if the block is escaping:
void
callNow(__attribute__((noescape)) void (^_Nonnull f)())
{
// f is not stored anywhere
}
With this attribute we promise not to save the block reference and not to call the block after the function has finished execution.