We want to know when the instances of the Circle
class will be removed from memory; that is, when the objects aren't referenced by any variable and automatic reference count mechanism decides that they have to be removed from memory. Deinitializers are special parameterless class methods that are automatically executed just before the runtime destroys an instance of a given type. Thus, we can use them to add any code we want to run before the instance is destroyed. We cannot call a deinitializer; they are only available for the runtime.
The deinitializer is a special method that uses the deinit
keyword in its declaration. The declaration must be parameterless, and it cannot return a value.
The following lines declare a deinitializer within the body of the Circle
class:
deinit { print("I'm destroying the Circle instance with a radius value of (radius).") }
The following lines show the new complete code for the Circle
class. The code file for the sample is included in the swift_3_oop_chapter_02_06
folder:
class Circle { var radius: Double init(radius: Double) { print("I'm initializing a new Circle instance with a radius value of (radius).") self.radius = radius } deinit { print("I'm destroying the Circle instance with a radius value of (radius).") } }
The code within the deinitilizer prints a message on the console indicating that the runtime will destroy a Circle
instance with a specific radius value. This way, we will understand when the code within the deinitializer is executed.
The following lines create two instances of the Circle
class named circleToDelete1
and circleToDelete2
. Then, the next lines assign new instances to both variables; therefore, the reference count for both objects reaches zero, and the automatic reference counting mechanism destroys them. Before the destruction takes place, Swift executes the deinitialization code. Enter the following lines in the Playground after adding the code for the deinitializer of the Circle
class. The code file for the sample is included in the swift_3_oop_chapter_02_07
folder:
var circleToDelete1 = Circle(radius: 25) var circleToDelete2 = Circle(radius: 50) circleToDelete1 = Circle(radius: 32) circleToDelete2 = Circle(radius: 47)
Use the previously explained Show Result and Value History options for the call to the print
function in both the initializer and the deinitializer. We will see the following messages in the Playground, as shown in the screenshot that follows them:
I'm initializing a new Circle instance with a radius value of 25.0. I'm initializing a new Circle instance with a radius value of 50.0. I'm initializing a new Circle instance with a radius value of 32.0. I'm destroying the Circle instance with a radius value of 25.0. I'm initializing a new Circle instance with a radius value of 47.0. I'm destroying the Circle instance with a radius value of 50.0.
The first two lines appear because we created instances of Circle
, and Swift executed the initialization code. Then, we assigned the result of creating a new instance of the Circle
class to the circleToDelete1
variable, and therefore, we removed the only existing reference to the instance with a radius value of 25.0
. Swift printed a line that indicates that it initialized a new instance with a radius value of 32.0
. After this line, Swift printed the line generated by the execution of the deinitializer of the Circle
instance that had a radius value of 25.0
.
Then, we assigned the result of creating a new instance of the Circle
class to the circleToDelete2
variable, and therefore, we removed the only existing reference to the instance with a radius value of 50.0
. Swift printed a line that indicates that it initialized a new instance with a radius value of 47.0
. After this line, Swift printed the line generated by the execution of the deinitializer of the Circle
instance that had a radius value of 50.0
.
The following screenshot shows the results of running the code in the Swift REPL:
The following screenshot shows the results of running the code in the web-based IBM Swift Sandbox:
The following lines create an instance of the Circle
class named circle3
and then assign a reference of this object to referenceToCircle3
. Thus, the reference count to the object increases to two. The next line assigns a new instance of the Circle
class to circle3
; therefore, the reference count for the object goes down from two to one. As the referenceToCircle3
variable stills holds a reference to the Circle
instance, Swift doesn't destroy the instance, and we don't see the results of the execution of the deinitializer. Enter the following lines in the Playground after the declaration of the Circle
class. Note that the screenshot only displays the results of the execution of the initializer in the Playground, and there is no execution for the deinitializer. The code file for the sample is included in the swift_3_oop_chapter_02_08
folder:
var circle3 = Circle(radius: 42) var referenceToCircle3 = circle3 circle3 = Circle(radius: 84)
The following screenshot shows the results of running the code in the Swift REPL:
The following screenshot shows the results of running the code in the web-based IBM Swift Sandbox:
18.116.49.243