I have an ObjC class inheriting from NSObject
that wraps some third-party library macros so that I can use their functionality in Swift. The class has an ivar that's a container type from the library. Creation of the container can fail, and if it does, the instantiation of my class should fail too. So I marked -init
as nullable
.
@interface BasketWrapper : NSObject
/**
* @abstract Create an empty basket
*/
- (nullable instancetype)init; // ⚠️ Conflicting nullability specifier
@end
@implementation
{
LibraryBasket * _basket;
}
- (instancetype)init
{
self = [super init];
if( !self ) return nil;
// Can't really do anything without the wrapped item.
_basket = LibraryBasket_Create();
if( !_basket ) return nil;
return self;
}
Unfortunately that -init
declaration produces a compiler warning
Conflicting nullability specifier on return types, '_Nullable' conflicts with existing specifier 'nonnull'
pointing at NSObject
's declaration.
As a workaround, I've marked the warning ignored with a pragma, and the method appears in Swift as failable.
Another option I considered was to mark plain -init
unavailable and make a class method, +empty
, instead. But then that's annoying because a) I can't use Swift initializer syntax, and b) init
is unavailable in the class's own implementation too.
Is there some way to override the nullability of the inherited init
without the warning?
You could declare a factory method having the same name as the type:
This will make the warning go away and allow you to make use of the failable initializer.