Search code examples
iosobjective-cswiftswift4xcode9-beta

Swift 4: XCode 9 Beta: Static factory method in Objective-C produces a valid object in Debugger, but NIL in the code


I have the following Swift class:

class VideoFaceDetectionController: UIViewController, IPVideoEmbedderControlDelegate {

var videoPlayer: IPVideoEmbedderControl?  // Note, not a weak reference
...

Then I have a method in Objective-C (in a referenced static library): generatePlayer(), as follows:

+ (IPVideoEmbedderControl*)generatePlayer
{
    IPVideoEmbedderControl* control = [IPLoad
        objectWithClass:[IPVideoEmbedderControl class]
        fromBundle:[NSBundle bundleWithIdentifier:videoFrameworkBundleID]];

    control.provider = [IPVideoPlaybackFactory getProvider];

    [control createEmbeddingView];
    return control;
}

I call it in Swift 4 like so:

videoPlayer? = IPVideoEmbedderControl.generatePlayer()
videoPlayer?.translatesAutoresizingMaskIntoConstraints = false;

Now I put a breakpoint on the second line (translatesAuto....), and inspect videoPlayer. It's NIL.

Now I do po IPVideoEmbedderControl.generatePlayer() in the console, and that produces a valid instance, that even has a frame:

 (lldb) po IPVideoEmbedderControl.generatePlayer()
▿ Optional<IPVideoEmbedderControl>

(lldb) po IPVideoEmbedderControl.generatePlayer().description
"<IPVideoEmbedderControl: 0x7faf88c19390; baseClass = UIControl; frame = (0 0; 320 349); autoresize = W+H; layer = <CALayer: 0x60c0002265c0>>"

So how can it be that in the debugger, a valid object is produced and returned, but in the code, a NIL value is returned from the same exact method?

I'm using Xcode Beta 9.0 (Release 5), with an iPad Air 2 (iOS 11) simulator. I can't verify on physical devices right now, because I don't have any running iOS 11 yet.


Solution

  • If this line is not a typo and you really use it in your app, it does not work as you expect:

    videoPlayer? = IPVideoEmbedderControl.generatePlayer()
    

    Try changing the line to:

    videoPlayer = IPVideoEmbedderControl.generatePlayer()
    

    You know the next line is a sort of Optional Chaining.

    videoPlayer?.translatesAutoresizingMaskIntoConstraints = false;
    

    When videoPlayer is nil, the rest of the line is safely ignored and it does nothing.

    All the same in the first line:

    videoPlayer? = IPVideoEmbedderControl.generatePlayer()
    

    When videoPlayer is nil, the rest of the line is safely ignored and it does nothing.