Skip to content

Commit a361954

Browse files
committed
Initially adding to repo
1 parent e74086e commit a361954

File tree

91 files changed

+6146
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+6146
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='3.0' sdk='macosx'>
3+
<sections>
4+
<code source-file-name='section-1.swift'/>
5+
</sections>
6+
<timeline fileName='timeline.xctimeline'/>
7+
</playground>
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
// ------------------------------------------------------------------------------------------------
2+
// Things to know:
3+
//
4+
// * Properties store values in classes, structures and enumerations.
5+
// ------------------------------------------------------------------------------------------------
6+
7+
// Here's a structure with a couple simple stored properties:
8+
struct FixedLengthRange
9+
{
10+
var firstValue: Int
11+
let length: Int
12+
}
13+
14+
// Structures must have all of their properties initialized upon instantiation.
15+
//
16+
// This won't compile since the struct includes properties that havn't been initialized with
17+
// default values:
18+
//
19+
// var anotherRangeOfThreeItems = FixedLengthRange()
20+
//
21+
// In order to instantiate a FixedLengthRange struct, we must use the memberwise initializer. Note
22+
// that this will initialize a constant property and a variable property inside the struct:
23+
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
24+
rangeOfThreeItems.firstValue = 6
25+
26+
// ------------------------------------------------------------------------------------------------
27+
// Lazy Stored Properties
28+
//
29+
// A Lazy Stored Property is a value that is not calculated until its first use.
30+
//
31+
// They are declared using the "@lazy" attribute and may not be constant.
32+
//
33+
// Global and local variables are all lazy, except that they don't need the @lazy attribute.
34+
//
35+
// Here, we'll define a couple classes to showcase Lazy Stored Properties. In this example, let's
36+
// assume that DataImporter is a time-consuming process, and as such, we will want to use a lazy
37+
// stored property whenever we use it. This way, if we end up never using it, we never pay the
38+
// penalty of instantiating it.
39+
class DataImporter
40+
{
41+
var filename = "data.txt"
42+
}
43+
44+
class DataManager
45+
{
46+
@lazy var importer = DataImporter()
47+
var data = String[]()
48+
}
49+
50+
// Now let's instantiate the data manager and add some simple data to the class:
51+
let manager = DataManager()
52+
manager.data += "Some data"
53+
manager.data += "Some more data"
54+
55+
// Notice how we haven't used the importer yet, so it is nil:
56+
manager
57+
58+
// So now let's access it:
59+
manager.importer.filename
60+
61+
// And now we see the importer was created:
62+
manager
63+
64+
// ------------------------------------------------------------------------------------------------
65+
// Computed Properties
66+
//
67+
// Computed properties don't store data, but rather use getters and setters for accessing values
68+
// that are computed up on request.
69+
//
70+
// Computed Properties are available for global as well as local variables.
71+
//
72+
// We'll start with a few structures that we'll use to show how computed properties work.
73+
struct Point
74+
{
75+
var x = 0.0, y = 0.0
76+
}
77+
struct Size
78+
{
79+
var width = 0.0, height = 0.0
80+
}
81+
82+
// The following structure includes a computed property with a Point type named 'center'. Notice
83+
// that 'center' is variable (not constant) which is a requirement of computed properties.
84+
//
85+
// Every computed property must have a getter, but does not need a setter. If we provide a setter,
86+
// we need to know the new value being assigned to the computed property. We've called this
87+
// value 'newCenter'. Note that this value does not have a type annotation because the computed
88+
// property already knows that it is a Point type. Providing a type annotation would be an error.
89+
struct Rect
90+
{
91+
var origin = Point()
92+
var size = Size()
93+
var center: Point
94+
{
95+
get
96+
{
97+
let centerX = origin.x + (size.width / 2)
98+
let centerY = origin.y + (size.height / 2)
99+
return Point(x: centerX, y: centerY)
100+
}
101+
set(newCenter)
102+
{
103+
origin.x = newCenter.x - (size.width / 2)
104+
origin.y = newCenter.y - (size.height / 2)
105+
}
106+
}
107+
}
108+
109+
// Here, we'll create a square from our Rect structure
110+
var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0))
111+
112+
// We can now get the center point, computed from the Rect's origin and size. Being a computed
113+
// property, we can treat it just like any other peroperty.
114+
let initialSquareCenter = square.center
115+
116+
// Since we provided a setter, we can also set the center point as if it is a stored property.
117+
// This will effectively update the Rect's origin and size based on the specified center point.
118+
square.center = Point(x: 15, y: 15)
119+
120+
// We can see that the origin has been updated from (0, 0) to (10, 10):
121+
square.origin
122+
123+
// Shorthand Setter Declaration
124+
//
125+
// The computed property's setter from the Rect structure provided a parameter on the setter named
126+
// 'newCenter'. If we don't specify this parameter, Swift will automatically generate an input
127+
// value named 'newValue' for us.
128+
//
129+
// Here, AlternativeRect is the same declaration as Rect above, except that the setter uses
130+
// Swift's default setter value, 'newValue':
131+
struct AlternativeRect
132+
{
133+
var origin = Point()
134+
var size = Size()
135+
var center: Point
136+
{
137+
get
138+
{
139+
let centerX = origin.x + (size.width / 2)
140+
let centerY = origin.y + (size.height / 2)
141+
return Point(x: centerX, y: centerY)
142+
}
143+
set
144+
{
145+
origin.x = newValue.x - (size.width / 2)
146+
origin.y = newValue.y - (size.height / 2)
147+
}
148+
}
149+
}
150+
151+
// We can also have a read-only computed property by simply omitting the setter:
152+
struct Cube
153+
{
154+
var width = 0.0, height = 0.0, depth = 0.0
155+
var volume: Double
156+
{
157+
get
158+
{
159+
return width * height * depth
160+
}
161+
}
162+
}
163+
164+
// Alternatively, Swift allows us to shorten the syntax of a read-only computed property by
165+
// omitting the get{} construct and inserting the code for the getter directly into the property
166+
// declaration:
167+
struct AnotherCube
168+
{
169+
var width = 0.0, height = 0.0, depth = 0.0
170+
var volume: Double
171+
{
172+
return width * height * depth
173+
}
174+
}
175+
176+
// Let's declare our structure and read the 'volume' property
177+
var cube = AnotherCube(width: 4, height: 5, depth: 2)
178+
cube.volume
179+
180+
// Since the 'volume' property is read-only, if we tried to assign a value to it, it would
181+
// would generate a compiler error.
182+
//
183+
// The following line of code will not compile:
184+
//
185+
// cube.volume = 8.0
186+
187+
// ------------------------------------------------------------------------------------------------
188+
// Property Observers
189+
//
190+
// Property observers allow us to respond to changes in a property's value. We can declare an
191+
// observer that contains our code that is run just before a property is set (optionally allowing
192+
// us to alter the value being set) and an observer that is run just after a property has been
193+
// modified.
194+
//
195+
// Property observers are available for global as well as local variables.
196+
//
197+
// These observers are not called when a property is first initialized, but only when it changes.
198+
//
199+
// Similar to setters, each 'willSet' and 'didSet' will receive a parameter that represents (in
200+
// the case of 'willSet') the value about to be assigned to the property and (in the case of
201+
// 'didSet') the value that was previously stored in the property prior to modification.
202+
class StepCounter
203+
{
204+
var totalSteps: Int = 0
205+
{
206+
willSet(newTotalSteps)
207+
{
208+
"About to step to \(newTotalSteps)"
209+
}
210+
didSet(oldTotalSteps)
211+
{
212+
"Just stepped from \(oldTotalSteps)"
213+
}
214+
}
215+
}
216+
217+
// Let's create an instance of StepCounter so we can try out our observer
218+
let stepCounter = StepCounter()
219+
220+
// The following will first call 'willSet' on the 'totalSteps' property, followed by a change to
221+
// the value itself, followed by a call to 'didSet'
222+
stepCounter.totalSteps = 200;
223+
224+
// Similar to setters, we can shorten our observers by omitting the parameter list for each. When
225+
// we co this, Swift automatically provides parameters named 'newValue' and 'oldValue'
226+
class StepCounterShorter
227+
{
228+
var totalSteps: Int = 0
229+
{
230+
willSet{ "About to step to \(newValue)" }
231+
didSet { "Just stepped from \(oldValue)" }
232+
}
233+
}
234+
235+
// We can also override the value being set by modifying the property itself within the 'didSet'
236+
// observer. This only works in the 'didSet'. If you attempt to modify the property in 'willSet'
237+
// you will receive a compiler warning.
238+
//
239+
// Let's try wrapping our value to the range of 0...255
240+
class StepCounterShorterWithModify
241+
{
242+
var totalSteps: Int = 0
243+
{
244+
willSet{ "About to step to \(newValue)" }
245+
didSet { totalSteps = totalSteps & 0xff }
246+
}
247+
}
248+
var stepper = StepCounterShorterWithModify()
249+
stepper.totalSteps = 345
250+
stepper.totalSteps // This reports totalSteps is now set to 89
251+
252+
// ------------------------------------------------------------------------------------------------
253+
// Type Properties
254+
//
255+
// Until now, we've been working with Instance Properties and Instance Methods, which are
256+
// associated to an instance of a class, structure or enumeration. Each instance gets its own copy
257+
// of the property or method.
258+
//
259+
// Type properties are properties that are attached to the class, structure or enumeration's type
260+
// itself and not any specific instance. All instances of a type will share the same Type Property.
261+
//
262+
// These are similar to 'static' properties in C-like languages.
263+
//
264+
// For Value types (structs, enums) we use the 'static' keyword. For Class types with the 'class'
265+
// keyword.
266+
//
267+
// Type properties can be in the form of stored properties or computed properties. As with normal
268+
// stored or computed properties, all the same rules apply except that stored type properties must
269+
// always have a default value. This exception is necessary because the initializer (which we'll
270+
// learn about later) is associated to a specific instance and as such, cannot be reliable for
271+
// initializing type properties.
272+
//
273+
// Here is a class with a couple of type properties
274+
struct SomeStructure
275+
{
276+
static var storedTypeProperty = "some value"
277+
278+
// Here's a read-only computed type property using the short-hand read-only syntax
279+
static var computedTypeProperty: Int { return 4 }
280+
}
281+
282+
// Similarly, here's an enumeration with a couple of type properties
283+
enum SomeEnum
284+
{
285+
static let storedTypeProperty = "some value"
286+
287+
static var computedTypeProperty: Int { return 4 }
288+
}
289+
290+
// Classes are a little different in that they cannot contain stored type properties, but may
291+
// only contain computed type properties
292+
class SomeClass
293+
{
294+
// The following line won't compile because classes aren't allowed stored type properties
295+
//
296+
// class var storedTypeProperty = "some value"
297+
298+
// This is read-only, but you can also do read/write
299+
class var computedTypeProperty: Int { return 4 }
300+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Timeline
3+
version = "3.0">
4+
<TimelineItems>
5+
<LoggerValueHistoryTimelineItem
6+
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=10168&amp;EndingColumnNumber=5&amp;EndingLineNumber=2&amp;StartingColumnNumber=4&amp;StartingLineNumber=2&amp;Timestamp=424364807.022397">
7+
</LoggerValueHistoryTimelineItem>
8+
</TimelineItems>
9+
</Timeline>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='3.0' sdk='macosx'>
3+
<sections>
4+
<code source-file-name='section-1.swift'/>
5+
</sections>
6+
<timeline fileName='timeline.xctimeline'/>
7+
</playground>

0 commit comments

Comments
 (0)