Need clarification regarding computed properties
There is no difference at all. This is a mere shortcut.
When you write
var testVariable {
get{
return _privateVariable
}
}
you can add setter at any point:
var testVariable {
set{
_privateVariable = newValue
}
get{
return _privateVariable
}
}
While the other case is useful to shorten your code when you don't need a setter.
Type Properties In Swift
You can define properties of a type to either be associated with the type itself (these are called Type properties), but you can also define properties to be associated with a specific instance of that type.
Type properties are usually used when you want to define something that is the same for each instance of a type and hence you shouldn't be able to change it specifically for each instance and you should be able to access it using the type itself without having to create an instance.
You can declare type properties using the static
keyword.
class MyClass {
static let typeProperty = "Type"
let instanceProperty = "Instance"
}
You can access the type property from the type itself:
let typeProp = MyClass.typeProperty
But to access an instance property, you need to create an instance of the type:
let instance = MyClass()
let instanceProp = instance.instanceProperty
Why no stored type properties for classes in swift?
The compiler error is "Class variables not yet supported" so it seems like they just haven't implemented it yet.
Need clarification on AnyObject in Swift
AnyObject
is a protocol. If you type it in a Playground and command click on it the following pops up:
/// The protocol to which all classes implicitly conform.
///
/// When used as a concrete type, all known `@objc` methods and
/// properties are available, as implicitly-unwrapped-optional methods
/// and properties respectively, on each instance of `AnyObject`. For
/// example:
///
/// .. parsed-literal:
///
/// class C {
/// @objc func getCValue() -> Int { return 42 }
/// }
///
/// // If x has a method @objc getValue()->Int, call it and
/// // return the result. Otherwise, return nil.
/// func getCValue1(x: AnyObject) -> Int? {
/// if let f: ()->Int = **x.getCValue** {
/// return f()
/// }
/// return nil
/// }
///
/// // A more idiomatic implementation using "optional chaining"
/// func getCValue2(x: AnyObject) -> Int? {
/// return **x.getCValue?()**
/// }
///
/// // An implementation that assumes the required method is present
/// func getCValue3(x: AnyObject) -> **Int** {
/// return **x.getCValue()** // x.getCValue is implicitly unwrapped.
/// }
///
/// See also: `AnyClass`
@objc protocol AnyObject {
}
what is the meaning when a property's type is a protocol in swift?
Property1 is anything that conforms to protocol A
. So this could either be another class, a struct, etc. Say you have a protocol Vegetable
and a class named Market
. You'll want to sell multiple types of Vegetable
, however, you want to make sure that the vegetables are for sale. You can do this with protocols.
protocol Vegetable {
var isForSale: Bool { get }
}
// Now let's create some vegetables
class Carrot: Vegetable {
let isForSale = true
}
class Spinach: Vegetable {
let isForSale = false
}
// This is our market.
class Market {
let vegetables: [Vegetable] = [Carrot(), Spinach()]
// Now we can check if the vegetables are for sale, because we know for sure that they conform to Vegetable so must implement this variable.
var forSale: [Vegetable] = {
vegetables.filter { $0.isForSale } // This will return [Spinach()]
}
}
Need clarification on Enumeration types in Swift
It's not really a Planet "Object" because Swift prefers the term "Type". An "Object" implies that it's an instance of a "class." Classes, enums & structs in Swift sort of blur the lines a bit vs. other languages.
Planet
is not a class, but an enumeration - a collection of related "member values". You're literally counting or "enumerating" all the various options within the group, and saying what name each one should go by. This provides a helpful alias to each value, allowing you to refer to the planets by name, instead of saying "Planet #1, #2, #3, #4, #5..."
Any situation where you have a finite collection of equal options may be a good candidate for an enum: "North, South, East, West" is another common example.
What you're doing here is declaring a new variable myPlanet
, and assigning its initial value to the Planet
enum's member value Mercury
. The Planet
Type is not explicitly declared, but is inferred from context - this new variable must be of Type Planet
in order to hold the desired value of .Mercury
.
An alternative declaration would be: var myPlanet: Planet = .Mercury
By explicitly declaring the Type of the var to be a Planet
you can omit Planet
from the righthand side.
Also, since it's a var
& not let
you could later change myPlanet
to any of the "member values" of the Planet enum. Since myPlanet
can only be 1 of the possible Planet
options, you only need to refer to the member value:
myPlanet = .Earth
You could not, however, change myPlanet
to a different Type (whether enum, struct, or class), because its type was already defined as Planet
.
See the Enumerations chapter of the Swift Programming Language Guide for more examples/details (though this example is the same, so you're probably reading it).
EDIT BASED ON COMMENTS:
To me Planet.Mercury means an enumeration type called Planet with only case Mercury inside of it.
Your myPlanet
variable is of Type Planet, with only the value .Mercury
assigned to it. "Planet.Mercury" as a statement is like pointing to "Menu of Planets, Value: Mercury."
A basic enum is a list of possible options, like a menu:
List of Planets to Choose From
1. Mercury
2. Venus
3. Earth
4. etc...
The variable myPlanet
is a container that can only have 1 value at a time.
Since you set it to 1 of the options listed within the Planet
enum definition, Swift infers that it must be of Type Planet
. From that point forward, this container is marked "Only For Planets" and its assigned value can only come from the enum list. The Planet
enum itself is static - it's the restaurant menu and always contains the same options (unless you edit the enum definition itself).
If I were to write it in terms of a class called Planet, I see it as myPlanet = Planet(name: "Mercury"). Do you have an analogy that can help me grasp the enumeration concept? – Walter
With the class example, you'd be using a method to initialize a Planet
instance with a property name
that you set to the String "Mercury". This is different in a number of ways. For one, "name" in this case is a property of Type String, which has getter/setter methods, etc. You could presumably set name
to whatever you want: Planet.name = "Walter"
You also have to access the property by its name, and provide it with a value. This is not true of enums.
With an enum, all you have is the predefined list of possible options.
Mercury, Venus, Earth, Mars, etc. The enum's "member values" are simply nicknames, similar to an alias for "Entry #1, Entry #2, Entry #3". If "Planet.Walter" is not in the predefined list, you cannot assign a variable of Type Planet to that value. It knows it has to be a Planet
but it won't find case Walter
among the options.
Also, the reason I am still confused has to do with accessing computed properties inside the enumeration. For example, if I had a computed property called size that is based on self inside the enumeration based on, the way to access is myPlanet.size. This means that it is equivalent to Planet.Mercury.size. How am I accessing a computed property through the case >value Mercury?
Computed properties are one of the places where Swift blurs the lines of traditional Object-Oriented Programming, because they exist in classes, enums, and structs, so it can get confusing.
myPlanet.size
doesn't necessarily equal Planet.Mercury.size
- it could be Planet.size
where size is a computed property returned from a function within the enum itself.
See this question for an example:
Swift Tour Card.createDeck() Returning [{(enum value), (enum value)}]
The following is an untested variation on the card deck example:
enum Planet {
case Mercury, Venus, Earth, Mars
func size() -> String {
switch self {
case .Mercury:
return "pretty darn small!"
case .Venus:
return "still small!"
case .Earth:
return "we think this is normal"
case .Mars:
return "slightly bigger than Earth"
}
}
}
var myPlanet: Planet = .Mercury
print(\myPlanet.size()) //"pretty darn small!"
myPlanet = .Mars
print(\myPlanet.size()) //"slightly bigger than Earth"
With this approach, the "size" function is a method of the Planet
enum, similar to how an object can have instance methods, or a struct can have methods too. Calling myPlanet.size()
after assigning a value is like saying "I'm a Type Planet, so if I look at myself, I know I'm a Mercury, so when I execute this method I have because I'm a Planet, I return the value for Mercury." Change the assigned value, and the method remains the same, but the returned value is now different, because myPlanet now has a different value.
Related Topics
How Is a Global Variable Set to Private Understood in Swift
Does _Arraytype or _Arrayprotocol Not Available in Swift 3.1
When Two Optionals Are Assigned to an If Let Statement, Which One Gets Unwrapped? Swift Language
Swift How to Sort Dict Keys by Byte Value and Not Alphabetically
Setting Observer for Swift Objects/Properties
Swift Tuple Has Unexpected Print Result
Getting the Time Remaining in the Time Interval of a Timer in Swift
How to Change the Order of Functions Triggered
Cannot Read Property 'Keycode' 'Character' Assertion Failure When Detect Modifier Key + Numeric Key
Is There Any Particular Use of Closure in Swift? and What's the Benefit
Error: Argument Type Double/String etc. Does Not Conform to Expected Type "Anyobject"
Alamofireimage How to Clean Memory and Cache
Hiding Dividers in Nssplitview
Node.Physicsbody.Joints Downcasting Error