3

I'm currently a novice in Swift, but I'm a maintainer of an Objective-C framework which is a wrapper around a C library, for which I'd like to have the nicest API possible.

I'm looking at this kind of code

/// The index checksum
@property (nonatomic, readonly, strong) GTOID * _Nullable checksum;

and wondering if the nullable annotation is warranted. Looking at the underlying C function,

const git_oid *git_index_checksum(git_index *index)
{
    return &index->checksum;
}

it's pretty obvious that, modulo memory allocation failures in the Obj-C wrapper,

- (GTOID *)checksum {
    const git_oid *oid = git_index_checksum(self.git_index);
    if (oid != NULL) {
        return [GTOID oidWithGitOid:oid];
    }
    return nil;
}

this is not nullable.

Or is it ?

Is there some specific guidelines into what's considered acceptable w.r.t nullability when bridging, especially in the face of allocation failures ? Would Swift's reaction be any different if I made that property nonnull and memory failed ?

tiennou
  • 487
  • 3
  • 13
  • If `return nil` can’t be deleted, it’s nullable. – matt Aug 17 '18 at 23:14
  • I could rewrite as `return [GTOID oidWithGitOid:git_index_checksum(…)]`, now the only thing that can return `nil` is the initializer itself, hence memory allocation failure. – tiennou Aug 17 '18 at 23:19
  • 3
    I agree. Historically, in Swift 1 _everything_ coming from Objective-C was nullable, because in theory any object reference can be `nil`. So our code was peppered with exclamation marks. Then Apple started hand-tweaking the APIs, introducing the nullable and nonnull attributes, so that if something could not _in fact_ return `nil` as a meaningful value, it was nonnull. Once you've pushed this back to the initializer, that's the situation and you've modernized the API correctly (in my view). – matt Aug 17 '18 at 23:30

0 Answers0