Swift Flashcards Preview

iOS > Swift > Flashcards

Flashcards in Swift Deck (89)
Loading flashcards...
1
Q

How to label loops?

A
sum = 0 
rowLoop: for row in 0..<8 {
columnLoop: for column in 0..<8 {
if row == column {
continue rowLoop
}
sum += row * column
}
}
2
Q

what is overloading?

A

When functions have the same name with different parameters.

3
Q

What is special Never return type in func?

A

wift that this function will never exit.

func infiniteLoop() -> Never {
while true {
} 
}
4
Q

Writing good functions

A

The best do /one simple task/, making them easier to mix, match, and model into more complex behaviors.

5
Q

nil coalescing

A

??

6
Q

make an ArraySlice

A

Use countable ranges

let upcomingPlayersSlice = players[1...2]
print(upcomingPlayersSlice[1], upcomingPlayersSlice[2])
// > "Bob Cindy\n"
7
Q

If you just want to know whether a dictionary has elements or not

A

is always better to use the isEmpty property. A dictionary needs to loop through all of the values to compute the count. isEmpty, by contrast, always runs in constant time no matter how many values there are

8
Q

If you want keep the key and set the value to nil

A

you must use the updateValue method.

dictionary[key] = nil removes the key completely

9
Q

Rule the hash value

A

always return the same hash value

10
Q

When use sets?

A

If you want to ensure that an item doesn’t appear more than once in your collection, and when the order of your items isn’t important.

11
Q

Swift Dictionaries

A
  • Are unordered collections of key-value pairs.

The keys are all of the same type, and the values*are all of the same type.

Use subscripting* to get values and to add, update or remove pairs.

  • If a key is not in a dictionary, lookup returns nil.

The key of a dictionary must be a type that conforms to the Hashable*protocol.

  • Basic Swift types such as String, Int, Double are Hashable out of the box.
12
Q

Swift Arrays

A
  • Are ordered collections of values of the same type.

Use subscripting*, or one of the many properties and methods, to access and update elements.

  • Be wary of accessing an index that’s out of bounds.
13
Q

Swift closure

A

Simply a function with no name; you can assign it to a variable and pass it around like any other value.

Closures are so named because they have the ability to “close over” the variables and constants within the closure’s own scope. This simply means that a closure can access, store and manipulate the value of any variable or constant from the surrounding context. Variables and constants used within the body of a closure are said to have been capturedby the closure.

A closure can capture*the variables and constants from its surrounding context.

  • A closure can be used to direct how a collection is sorted.
14
Q

trailing closure syntax

A

you declare body after other parameters as its body of func, but its body of closure that are inside.

15
Q

compactMap vs map

A

This is almost the same as map except it creates an array and tosses out the missing values

16
Q

Swift character

A

A Character is grapheme cluster and is made up of one or more code points.

You use special (non-integer) indexes to subscript into the string to a certain grapheme cluster.

17
Q

rapheme cluster

A

A Character is grapheme clusterand is made up of one or more code points.

18
Q

What is character in swift

A

A Character is grapheme clusterand is made up of one or more code points.

19
Q

What slicing a string produce?

A

Slicing a string produce a substring with type Substring, which shares storage with its parent String.

You can convert from a Substring to a String by initializing a new String and passing the Substring.

20
Q

Structures

A

They are value types, which means their values are copied on assignment.

Structures are also very /fast/compared to their reference alternatives,

21
Q

What is faster? Structures or classes? Why?

A

Structures. Structs rely on the faster stack while classes rely on the slower heap

22
Q

Stored properties vs computed properties. What have each of them?

A

Stored properties allocate memory to store a value.

Computed properties are calculated each time your code requests them and aren’t stored as a value in memory.

Do not confuse property observers with getters and setters. A stored property can have a didSet and/or a willSet observer. A computed property has a getter and optionally a setter

23
Q

read-only computed property vs read-write computed property

A

read-write computed property: a getter and a setter.

read-only: only getter

24
Q

lazy modifier

A

The lazy modifier prevents a value of a stored property from being calculated until your code uses it for the first time. You’ll want to use lazy initializationwhen a property’s initial value is computationally intensive or when you won’t know the initial value of a property until after you’ve initialized the object.

25
Q

Should I implement this value getter as a method or as a computed property?

A

Properties hold values that you can get and set, while methods perform work. Sometimes this distinction gets fuzzy when a method’s sole purpose is to return a single value.

26
Q

memberwise initializer

A

auto-generated initializer

27
Q

Methods in structures cannot change the values of the instance without

A

being marked as mutating -> self is inout in mutating methods.

28
Q

The heap vs. the stack

A

When you create a reference type such as class, the system stores the actual instance in a region of memory known as the heap. Instances of a value type such as a struct resides in a region of memory called the stack, unless the value is part of a class instance, in which case the value is stored on the heap with the rest of the class instance.

29
Q

What is stack?

A

The system uses the stack to store anything on the immediate thread of execution; it is tightly managed and optimized by the CPU. When a function creates a variable, the stack stores that variable and then destroys it when the function exits. Since the stack is so strictly organized, it’s very efficient, and thus quite fast.

30
Q

What is heap?

A

The system uses the heap to store instances of reference types. The heap is generally a large pool of memory from which the system can request and dynamically allocate blocks of memory. Lifetime is flexible and dynamic. The heap doesn’t automatically destroy its data like the stack does; additional work is required to do that. This makes creating and removing data on the heap a slower process, compared to on the stack.

31
Q

When you create an instance of a class, your code requests a block of memory - where?

A

on the heap to store the instance itself.

32
Q

When you create an instance of a struct (that is not part of an instance of a class) where instance is stored?

A

the instance itself is stored on the stack, and the heap is never involved.

Structure doesn’t have a heap. Heap is classes reference for stack. Structure keeps on stack.

33
Q

When to use a class versus a struct?

A

Structs are faster. Structs rely on the faster stack while classes rely on the slower heap.

If you will have many more instances (hundreds and greater), or if these instances will only exist in memory for a short time — lean towards using a struct.

If your data will never change or you need a simple data store, then use structures.

If you need to update your data and you need it to contain logic to update its own state, then use classes.

Use classes when you want reference semantics; structures for value semantics.

Think about comparing. User vs User (class). Address vs Address. (struct)

Often, it’s best to begin with a struct. If you need the added capabilities of a class sometime later, then you just convert the struct to a class.

34
Q

Equality of structs

A

instances of value types, which /are/values, are considered equal if they are the same value.

35
Q

Equality of classes

A

An objectis an instance of a reference type, and such instances have identitymeaning that every object is unique. No two objects are considered equal simply because they hold the same state. Hence, you use === to see if objects are truly equal and not just containing the same state.

36
Q

If your instance will have a longer lifecycle in memory, or if you’ll create relatively few instances. Class or struct?

A

then class instances on the heap shouldn’t create much overhead.

37
Q

If you will have many more instances (hundreds and greater), or if these instances will only exist in memory for a short time.

A

lean towards using a struct

38
Q

If your data will never change or you need a simple data store

A

lean towards using a struct

39
Q

If you need to update your data and you need it to contain logic to update its own state

A

then use classes

40
Q

Structures vs. classes

A

Structures

  • Useful for representing values.
  • Implicit copying of values.
  • Becomes completely immutable when declared with let.
  • Fast memory allocation (stack).

Classes
* Useful for representing objects with an identity.
* Implicit sharing of objects.
* Internals can remain mutable even when declared with let.
Mutability introduces state*, which adds complexity when managing your objects.
* Slower memory allocation (heap).

41
Q

Swift language dispatch

A

static dispatch Swift has a strong type system

42
Q

When call super when overriding methods? Why?

A

It’s best practice to call the super version of a method first when overriding. That way, the superclass won’t experience any side effects introduced by its subclass, and the subclass won’t need to know the superclass’s implementation details.

43
Q

Benefits to make a class as final

A

This tells the compiler it doesn’t need to look for any more subclasses, which can shorten compile time, and it also requires you to be very explicit when deciding to subclass a class previously marked final.

44
Q

What initializers in subclasses are required to do? Why?

A

to call super.init

because without it, the superclass won’t be able to provide initial states for all its stored properties

45
Q

When to call super? Overriding vs init?

A

in init you have to call super after, in overriding at the beginning

46
Q

What is two-phase initialization?

A

Phase one: Initialize all of the stored properties in the class instance, from the bottom to the top of the class hierarchy. You can’t use properties and methods until phase one is complete.

Phase two: You can now use properties and methods, as well as initializations that require the use of self.

class StudentAthlete: Student {
var sports: [String]
init(firstName: String, lastName: String, sports: [String]) {
// 1
self.sports = sports
// 2
let passGrade = Grade(letter: "P", points: 0.0,
// 3 
credits: 0.0)
super.init(firstName: firstName, lastName: lastName)
// 4
recordGrade(passGrade)
} 
// original code
} 

After super.init returns, the initializer is in phase 2, so you call recordGrade(_:).

Swift classes use two-phase initializationas a safety measure to ensure all stored properties are initialized before they are used.

47
Q

What the compiler forces a convenience initializer to do instead of handling the initialization of stored properties itself?

A

to call a non-convenience initializer (directly or indirectly) A non-convenience initializer is called a designated initializer and is subject to the rules of two-phase initialization.

48
Q

When mark initializer as convenience?

A

if you only use that initializer as an easy way to initialize an object, but you still want it to leverage one of your designated initializers.

49
Q

Compiler rules for using designated and convenience initializers

A
  1. A designated initializer must call a designated initializer from its immediate superclass.
  2. A convenience initializer must call another initializer from the same class.
  3. A convenience initializer must ultimately call a designated initializer.
50
Q

When and why to subclass

A
Single responsibility
Strong types
Shared base classes
Extensibility
Identity
51
Q

If your goal is to share behavior (what objects /can do/) between types you should prefer

A

protocols over subclassing

52
Q

Most important features of classes

A

Class inheritance and polymorphism

53
Q

What is encapsulation

A

“This hidden internal state is sometimes referred to as the invariant, which your public interface should always maintain. Preventing direct access to the internal state of a model and maintaining the invariant is a fundamental software design concept known as encapsulation.”

54
Q

What is access control and for what it is useful

A

“Note: Access control is not a security feature that protects your code from malicious hackers. Rather, it lets you express intent by generating helpful compiler errors if a user attempts directly access implementation details that may compromise the invariant, and therefore, correctness.”

55
Q

Access modifiers

A
"private: Accessible only to the defining type, all nested types and extensions on that type within the same source file.
fileprivate: Accessible from anywhere within the source file in which it's defined.
internal: Accessible from anywhere within the module in which it's defined. This is the default access level.
"public: Accessible from anywhere within the module in which it is defined, as well as another software module that imports this module.
open: The same as public, with the additional ability of being able to be overridden by code in another module."
56
Q

Extensions by behavior

A

“An effective strategy in Swift is to organize your code into extensions by behavior. You can even apply access modifiers to extensions themselves, which will help you categorize entire sections of code as public, internal or private “

57
Q

Public and open vs module

A

public and open allow code to be accessed from another module. The open modifier additionally allows entities to be overridden by other modules.

58
Q

Organize an if-else-if. What to use instead?

A

Use switch and where

59
Q

Iterating through an array of optional values that you need to unwrap and ensure are not nil

A

compactMap

60
Q

The Error protocol can be implemented by any type you define, but it’s especially well- suited to

A

enumerations

61
Q

The Error protocol tells the compiler that this enumeration can be used

A

to represent errors that can be thrown

62
Q

After your program throws an error, you need to handle that error. What is your two ways to do it?

A

You can handle your errors immediately, or you can bubble them up to another level.

63
Q

Code that can throw errors must always be inside

A

a do block which creates a new scope.

64
Q

exact points where errors can be thrown must be marked with

A

try

65
Q

When calling an error-throwing function

A

you must embed the function call in a do

block. Within that block, you try the function, and if it fails, you catch the error.

66
Q

What is Codable?

A

“typealias Codable = Encodable & Decodable”

67
Q

“Automatic encoding and decoding”

A

match property names with json

68
Q

“Encoding and decoding custom types”

A

use coding Keys enum - “Renaming properties with CodingKeys”

69
Q

“Manual encoding and decoding”

A

The decode - init

The encore - func

70
Q

encodeIfPresent and decodeIfPresent

A

optional

71
Q

What are closures by default?

A

Closures are non-escaping by default, meaning that when the function using the closure returns it will never be used again.

72
Q

What is the capture list?

A

When dealing with objects, remember that “constant” has a different meaning for reference types. With reference types, a capture list will cause the closure to capture and store the current reference stored inside the captured variable. Changes made to the object through this reference will still be visible outside of the closure.

73
Q

“Value semantics are good for representing

A

inert, descriptive data — numbers, strings, and physical quantities like angle, length or color, don’t forget mathematical objects like vectors and matrices, pure binary data and collections of such values, and lastly, large rich structures made from such values, like media.”

“But the items on the value semantics list are all values. They lack identity, so it is meaningless to talk about two things being equal but distinct. If we agree x equals five, there is no further question about which five it equals. Five is five.”

74
Q

“Reference semantics are good for representing

A

distinct items in your program or in the world. For example: constructs within your program such as specific buttons or memory buffers; an object that plays a specific role in coordinating certain other objects; or a particular person or physical object in the real world.”

“The underlying logic here is that the referenceable items are all objects, meaning they all have a distinct identity. Two people could be alike in all physical attributes, but they are still distinct people. Two buffers could hold equal byte patterns, but they are still distinct buffers.”

75
Q

Implementing value semantics

A
  1. Primitive value types
  2. Composite value types
  3. Reference types
    4: value types containing mutable reference types
76
Q

value semantics - Composite value types

A

“Composite value types, for example struct or enum, follow a simple rule: A struct supports value semantics if all its stored properties support value semantics”

“Incidentally, since an Array provides the same semantics as a struct with a property of type Element, this case also tells you whether arrays support value semantics. They do, but only if their element type does.”

77
Q

value semantics - Reference types

A

“The solution is straightforward: To define a reference type with value semantics, you must define it to be immutable. In other words, build it so it’s impossible to change the instance’s value after initialization. To achieve this, you must ensure that all its stored properties are constant and only use types with value semantics.”

78
Q

value semantics - value types containing mutable reference types

A

copy-on-write

79
Q

“Recipes for value semantics For a reference type (a class):

A

The type must be immutable, so the requirement is that all its properties are constant and must be of types that have value semantics.

80
Q

“Recipes for value semantics “For a value type (a struct or enum):

A

For a value type (a struct or enum):
A primitive value type like Int always has value semantics.

“If you define a struct type with properties, that type will have value semantics if all of its properties have value semantics.

Similarly, if you define an enum type with associated values, that type will have value semantics if all its associated values have value semantics.”

81
Q

“Recipes for value semantics “For a value type (a struct or enum):

A

“Choose the “value-semantics access level”, that is, the access level that’ll expose an interface that preserves value semantics.
Make note of all mutable reference-type properties, as these are the ones that spoil automatic value semantics. Set their access level below the value-semantics level.
Define all the setters and mutating functions at and above the value-semantics access level so that they never actually modify a shared instance of those reference-type properties, but instead assign a copy of the instance to the reference-type property.

82
Q

“Value types and reference types differ in their assignment behavior. “

A

“Value types use assign-by-copy; reference types use assign-by-reference. This behavior describes whether a variable copies or refers to the instance assigned to it.”

“This assignment behavior affects not only variables but also function calls.”

83
Q

“Structural sharing is

A

when distinct instances refer to a common backing instance that contributes to their value. This economizes storage since multiple instances can depend on one large shared instance. But if one instance can modify the shared backing instance, it can indirectly modify the value of other instances, so that the distinct instances are not fully independent, undermining value semantics.

84
Q

“Copy-on-write is

A

the optimization pattern where a type relies on structural sharing but also preserves value semantics by copying its backing instance only at the moment when it itself is mutated. This allows the efficiency of a reference type in the read-only case, while deferring the cost of instance copying in the read-write case.”

85
Q

“Reference types also have value semantics if you

A

define them to be fully immutable, meaning that they cannot be modified after initialization. To do this it suffices that all their stored properties are read-only and of types that themselves have value semantics.”

86
Q

Protocol benefits

A

multiple inheritance

for types that don’t support inheritance

87
Q

Lifecycle of the @nonescaping closure:

A
  1. Pass the closure as function argument, during the function call.
  2. Do some additional work with function.
  3. Function runs the closure.
  4. Function returns the compiler back.a
88
Q

Ways to store @escaping closures

A

Storage: When you need to preserve the closure in storage that exist in the memory, past of the calling function get executed and return the compiler back. (Like waiting for the API response)

Asynchronous Execution: When you are executing the closure asynchronously on dispatch queue, the queue will hold the closure in memory for you, to be used in future. In this case you have no idea when the closure will get executed.

89
Q

Lifecycle of the @escaping closure:

A
  1. Pass the closure as function argument, during the function call.
  2. Do some additional work in function.
  3. Function execute the closure asynchronously or stored.
  4. Function returns the compiler back.