-1

I'm in the process of introducing Swift to an Objective-C app.

I have a UIViewController subclass where I want to hide a button if a certain property is nil. My Swift code looks like this, using optional binding:

if let optionalVar = modelObject.propertyThatCouldBeNil {
   button.setTitle(...)
} else {
   button.hidden = true
}

My hope was that when propertyThatCouldBeNil was nil, the if wasn't satisfied and control would continue to the else. But that's not what's happening. In fact if I set a breakpoint, what I see is...

(lldb) po optionalVar
nil
(lldb) po modelObject.propertyThatCouldBeNil
▿ Optional<Optional<String>>
  - some : nil

That latter one is what's tripping me up a bit. I think it should be Optional, not nested, correct?

Some more info...

Since I'm using modelObject throughout this class, for convenience it's defined as an implicitly unwrapped optional...

var modelObject : ModelObjectClass!

ModelObjectClass is actually an Objective-C class, and the property is read only and declared as such...

@property (readonly, nullable) NSString *propertyThatCouldBeNil;

In it's implementation, it actually acts as a sort of proxy for another ready only property...

- (NSString*) propertyThatCouldBeNil {
   return self.someOtherProperty;
}

And the someOtherProperty is nullable as well...

@property (nullable, nonatomic, retain) NSString *someOtherProperty;

Any insight as to why the optional binding isn't working as I expect?

bpapa
  • 21,409
  • 25
  • 99
  • 147
  • I just tried, seems to be working with xcode 8 and swift 3 –  Oct 27 '16 at 17:41
  • Can you provide complete minimal verifiable example code, allowing me to reproduce the phenomenon on my own machine? – matt Oct 27 '16 at 18:50
  • @matt I'll work on that... in the meantime, not sure if it matters but the propertyThatCouldBeNil definition is actually in an Objective-C protocol that the class that contains someOtherProperty conforms to. – bpapa Nov 01 '16 at 15:52
  • Understood, but that is not enough for me to guess what your code must be. I'm not going to sit here trying various combinations based on your vague hints. It is _your_ job to provide _specifics_. – matt Nov 01 '16 at 16:01
  • Cool thanks for explaining how SO works I just got here yesterday! – bpapa Nov 01 '16 at 16:03
  • So you are rude in the way you write comments _and_ rude in the way you ask questions. Nice. – matt Nov 01 '16 at 17:31
  • Chill out bud. You started with what my "job" was. Anyway it appears that I'm seeing this because the property was declared as @optional in my Objective-C protocol, and it looks like that means it's a Swift optional automatically. – bpapa Nov 01 '16 at 18:00
  • 1
    That is correct bud. You might want to read my book's section on this topic: http://www.apeth.com/swiftBook/ch04.html#SECoptionalProtocol – matt Nov 01 '16 at 18:06
  • Matt, you are a real bud. :) Sorry for "I'll work on that", I meant it in the sense that I was actually working on it. I will also give your book a look, I'm not sure where in the official docs they've explained what I've come to realize, unless it was buried in a WWDC session somewhere. – bpapa Nov 01 '16 at 18:08

1 Answers1

1

Seems to be working with me

@interface ModelObjectClass : NSObject
    @property (readonly, nullable) NSString *propertyThatCouldBeNil;
    @property (nullable, nonatomic, retain) NSString *someOtherProperty;
    - (nullable NSString*) propertyThatCouldBeNil;
@end

@implementation ModelObjectClass
    - (nullable NSString*) propertyThatCouldBeNil {
        return self.someOtherProperty;
    }
@end