1

Earlier I had a question that I figured out, but the answer led to another question. What is the !? syntax, I haven't seen it anywhere else, but it was the only way I could get the code to compile. Can someone tell me what "!?" the syntax means? Is it a bug? The link shows all code.

field.superview!?.superview?.layer.borderWidth = 2
Community
  • 1
  • 1
hidden-username
  • 2,610
  • 3
  • 14
  • 19
  • 3
    I could explain it, but the code you've arrived at is so bad that it seems hardly worth it. It would be better to write the code better. – matt Jan 31 '15 at 02:47
  • 1
    How is that bad code? – hidden-username Jan 31 '15 at 02:48
  • 3
    In every way. It's not the right way to reach the alert view itself, if that's what you're trying to do. It doesn't cast when it needs to cast. It tries to pack too much into one line without clarifying what's happening. It's just nutty. And that's why you end up with the double optional. – matt Jan 31 '15 at 02:49
  • 2
    Plus what you're doing in your original code is so wrong. This should not be a UIAlertController. If you want completely control of your view, write your own view controller. It's so easy to do. There's no excuse for what you're doing with all those text fields. – matt Jan 31 '15 at 02:50
  • I actually usually like your posts, really liked using your delay function, but this is just unhelpful. Im not asking how my code should be factored, I'm asking about the syntax. And your explanation is quite vague. – hidden-username Jan 31 '15 at 02:57
  • 1
    So you really are just asking about the syntax? Then learn Swift. You can easily figure it out if you read my Swift tutorial. There are two things you need to know about: [Optionals](http://www.apeth.com/swiftBook/ch03.html#_optional), and [AnyObject](http://www.apeth.com/swiftBook/ch04.html#_suppressing_type_checking). – matt Jan 31 '15 at 03:11
  • And, going back to your earlier question, if you want to learn how to write your own alert-type view controller properly, I've written you sample code showing how to do get started: https://github.com/mattneub/custom-alert-view-iOS7 – matt Jan 31 '15 at 03:12
  • I appreciate your help, I have been learning swift, I have read apple's book and i reference it often. I checked out you links, but i still don't get what's happening here. I know using the AlertController that way is not intended, and I did try my own UIView and a delegate at first but it was a pain because I'm presenting over a Parse PFLoginVC which I did not subclass. I went back to the code and even tried, Sorry i can't get comment code to format properly. I still had to forcibly unwrap view. And i don't know why. – hidden-username Jan 31 '15 at 03:31
  • if let view = field.superview { view!.superview!.layer.borderWidth = 2 }' – hidden-username Jan 31 '15 at 03:31
  • "if let view = field.superview? { view.superview?.layer.borderWidth = 2 }" – hidden-username Jan 31 '15 at 03:36
  • Is this last one better, purely for a syntax viewpoint? – hidden-username Jan 31 '15 at 03:37
  • OK, I've answered the question just to put an end to this silliness. – matt Jan 31 '15 at 03:41

1 Answers1

4

A UIAlertController's textFields property is an [AnyObject]?. So this is what you are doing:

let textFields : [AnyObject]? = [UIView()] // textFields is an Optional
for field in textFields! { // you unwrap the Optional, but now...
    // ... field is an AnyObject
    let v1 = field.superview // now v1 is a UIView?!
}

Do you see the problem? An AnyObject has no superview property - or any other properties. Swift will allow this, but only at the expense of wrapping the result in an Optional, because this might not be a UIView and so it might not respond to superview (as I explain here). So now it calls superview for you. But superview itself yields an Optional (because, if this is a UIView, it might have no superview). Hence the double Optional.

But if you had cast to start with, that would not have happened:

for field in textFields as [UIView] {

Now field is a UIView and it is legal to send it the superview message, and you just have to deal with the single unwrapping of each superview.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • That makes perfect sense. Thank you for taking the time. I didn't realize it was [AnyObject]? thought it was [UITextField]? I would think an API returning an array of textFields would have casted them, but I guess I should look at the documentation closer. Ill check out the custom alert view, thank you for your help. – hidden-username Jan 31 '15 at 03:47
  • "I would think an API returning an array of textFields would have casted them" Yes, that's a fair point. But until the APIs are rewritten, it's not reality. See my comment about that here: http://www.apeth.com/swiftBook/ch04.html#_swift_array_and_objective_c_nsarray – matt Jan 31 '15 at 03:48
  • @matt can you explain this? `UIApplication.sharedApplication().delegate!.window!?.rootViewController` – beretis Aug 01 '15 at 08:55
  • Yes, even I can now :) if anyone interested here it is[http://stackoverflow.com/questions/29920427/swift-optional-of-optional] – beretis Aug 01 '15 at 13:03
  • Actually, this question right here answers it, @beretis. It's exactly the same situation. – matt Aug 01 '15 at 13:13