问题
I notice when I'm writing in Swift, if I declare a label in the ViewController
as either var label: UILabel!
or var label = UILabel()
, and then initialize them in the viewDidLoad
method, they both seem to, functionally, work identically. So what is the difference between these two?
On a related note, when I declare var label: UILabel!
I have to write label = UILabel(frame:CGRectMake(...))
, but if I use var label = UILabel()
I have to write label.frame = CGRectMake(...)
. Is this because var label = UILabel()
is both declaring and instantiating a class object whereas var label: UILabel!
is simply declaring a variable of a type? I'm confused about what's actually going on here.
Thanks in advance!
回答1:
var label: UILabel!
is declaring that you have a UILabel variable that may be empty (Optional), but you can access it pretending as if it will not - usually that means it would be an IBOutlet that would be set by the interface storyboard on load, before you tried to use the label.
var label = UILabel()
is declaring that you have a label that will always hold a label, and can never be nil. It is ALSO creating an instance of a UILabel when a class instance is created, even though you say you assign a different label to the variable in viewDidLoad()
There's no difference in access, but it does mean no matter when you use that variable it will hold a real value and not be nil.
They both are variables of type UILabel
.
I'm not sure why you could not not set the variable to a new UILabel
using the CGRect
constructor, that should be possible. Perhaps at one point you had said let label = UILabel()
, which would mean it was a fixed variable that could not hold a new value - so all you could do was alter the frame of the variable that exists already.
The best approach for something like what you are doing is to declare the variable an Optional:
var label : UILabel?
Which makes it an true Optional, and makes sure that you do not accidentally write code that accesses the variable badly if it's never been set, or sets a value to your first label before you assign the "real" UILabel in your viewDidLoad
method. Accessing is a little different, but not much harder - to set text you just use the "?" syntax to optionally call the property if the instance has been set:
label?.text = "fred"
回答2:
You are correct. UILabel()
calls the UILabel
no-arg constructor and assigns that object reference to the label
variable. So that's a declaration and an initialization.
In the case of the constructor, label
is not an optional and is inferred to be the straightforward UILabel
type, but in the case of your declaration label
is an Optional
type. The ! just means it's an optional with a force-unwrapping, so that when you use it as a value, you don't have to type the !; however if you declare it as force-unwrapped and you use it when it's nil
-valued, your program crashes.
Note also that you're not allowed to declare:
var label: UILabel
as a class member unless you initialize it in all of your constructors, before the (possibly implicit) call to super.init() because it will complain that there is no initial value, so it might be referenced with no known value -- something the Swift compiler prevents.
来源:https://stackoverflow.com/questions/28734235/whats-the-difference-between-var-label-uilabel-and-var-label-uilabel