I'm following a tutorial learning about delegates and protocols while using the UITextField object. In the tutorial I noticed that I didn't have to instantiate the NSCharacterSet object first by typing
let letterCharacters = NSCharacterSet()
The tutorial's code worked by reaching directly for the letters variable of NSCharacterSet which is mind blowing. I assumed objects always needed to be instantiated first before using them or making reference to them. Here is the full function that works:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let existingTextHasDecimalSeperator = textField.text?.range(of: ".")
let replacementTextHasDecimalSeperator = string.range(of: ".")
let letterCharacters = NSCharacterSet.letters
let foundCharacter = string.rangeOfCharacter(from: letterCharacters)
if existingTextHasDecimalSeperator != nil && replacementTextHasDecimalSeperator != nil {
return false
} else if foundCharacter != nil {
return false
} else {
return true
}
}
Why am I allowed to use NSCharacterSet.letters directly instead of creating a NSCharacterSet object first?
From the Apple documentation:
class var letters: CharacterSet
A character set containing the characters in Unicode General Category L* & M*.
The key piece here is the class part of that definition. If it is a class variable, than you do not need to instantiate the object with NSCharacterSet()
.
A quick primer on variable types.
CharacterSet.letters
for examplecharacterSet.inverted
would be an example of thisTypically, a class variable would never change so it has no need to maintain state. An instance variable likely will.