Need Clarification for Swift Type Properties

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



Leave a reply



Submit