The method of Swift tutorial is explained in detail

  • 2020-05-13 03:31:02
  • OfStack

The method is associated with a specific type of function. Class, structure, enumeration all can define instance methods that encapsulate specific tasks and functions to handle one instance of a given type. Classes, structures, and enumerated types can also define methods, the associated types themselves. The type method is similar to the objective and c class methods.

The structure and enumeration that define the methods swift and C and objective and C are a significant difference. In objective and c, classes are the only type 1 that can define methods. At swift, you can choose whether you want to define a class, structure, or enumeration, and you have the flexibility to define method types.

1. Instance method

An instance method is a function that belongs to a particular class, structure, or enumeration instance. They support the functionality of these instances, either by providing methods to access and modify instance properties, or by providing functionality with the purpose of the instance. Instance methods have exactly the same syntax functions, such as function descriptions
Write an instance method inside the open and close brackets of the type you belong to. An instance method has implicit access to all other instance methods and properties of that type. An instance method can only be called from a specific instance of the class to which it belongs, and it cannot access a nonexistent instance.
Here, we define a simple counter class that can be used as an example to count the number of times an action has occurred:


class Counter {
var count = 0
func increment() {
count++
}
func incrementBy(amount: Int) {
count += amount
}
func reset() {
count = 0
}
}

The counter class can define three instance methods:
Increment the counter by 1.
incrementBy(amount:Int) increments the counter by the specified integer amount.
Reset reset the value of the counter to zero.
The count class also declares a variable property that counts and tracks the current counter value.
You call instance methods that have properties of the same syntax

 
let counter = Counter()
// the initial counter value is 0
counter.increment()
// the counter's value is now 1
counter.incrementBy(5)
// the counter's value is now 6
counter.reset()
// the counter's value is now 0

Methods with local and external parameter names

A function parameter can have a local name (used in the body of the function) and an external name (used when the function is called), with the name of the external parameter. The same is true for method parameters, because methods are type-dependent functions. However, the default behavior of local and external names is different for functions and methods.

The method in Swift is very similar to the peers in objective and c. In objective, the name of a method in Swift usually refers to the first argument of a method that USES preposition, etc., or, as in the example of counter class in the incrementBy method above. Using a method that can be interpreted as a judgment is called preposition. Swift makes the method establishment naming convention easy to write by using a different default method.

Specifically,Swift gives the first parameter name method the default local parameter name, and the second and subsequent parameter names the default local and external parameter names. This convention can be invoked in the familiar objective, c, and allows you to express method calls without having to match your parameter names.

Consider this alternative version of the counter class, which defines a more complex form of the incrementBy method:

 
class Counter {
var count: Int = 0
func incrementBy(amount: Int, numberOfTimes: Int) {
count += amount * numberOfTimes
}
}

There are two parameters-amount and numberOfTimes incrementBy methods. By default,Swift treats amount as a local name, but numberOfTimes as a local and external name. The method you call is as follows:

 
let counter = Counter()
counter.incrementBy(5, numberOfTimes: 3)
// counter value is now 15

You do not need to define an external parameter name as the first parameter value, because it is the explicit function name incrementBy. However, the second parameter is qualified by the external parameter name.
This default behavior is valid for external methods if you have an numberOfTimes parameter before writing an hash symbol (#) :


func incrementBy(amount: Int, #numberOfTimes: Int) {
count += amount * numberOfTimes
}

The default behavior described above writes the same method definition to Swift, with syntax similar to objective and c, which can be called more easily.

Modify the behavior method of the external parameter name

Sometimes it is useful to provide the parameter name of the first parameter of an external method, even if this is not the default behavior. You can add an explicit external name yourself, or you can use the local name as the external name with the first parameter flag of a name with a hash prefix.
Conversely, if you do not want to provide an external name or subsequent parameter for the second method, override the default behavior by using the underscore character (_) as an explicit external parameter name parameter.

Self properties

Each instance of a type has what is called an implied self attribute, which is completely equivalent to the instance itself. You can use this implicit self property to reference its own instance methods in the current instance.

In the example above, the incremental method can also be written like this:


func increment() {
self.count++
}

In practice, you don't need to write self, which is very frequent in your code. If you do not explicitly write self, Swift assumes that you are referring to the current instance's properties or methods whenever you use one of the known properties or method names in one method. This hypothesis proves that the counters in the three instance methods use count (rather than self.count).
The main exception occurs when an instance method has the same parameter name as the instance property. In this case, parameter names take precedence and it is necessary to refer to the properties in a more qualified way. You can distinguish between the parameter name of the implicit self property and the property name.
If one method parameter is called x and one instance property is also called x, then two x can be automatically disambiguated in Swift.

 
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOfX(x: Double) -> Bool {
return self.x > x
}
}
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOfX(1.0) {
println("This point is to the right of the line where x == 1.0")
}
// prints "This point is to the right of the line where x == 1.0"

If there is no self prefix, Swift assumes that the two USES of x are called X method parameters

Modify the instance method of the value type

Structure and enumeration value types. By default, a property of a value type cannot modify its instance methods
However, if you need to modify the property structure or enumeration in a particular method, you can choose the method's changing behavior. But any change will cause the method it has to write to end up back in its original structure. When the method ends, it is also possible to assign a completely new instance to its implicit self property, and this new instance will replace the existing one.
You can select the method of embedding the variable keyword into the function keyword before this behavior:


struct Point {
var x = 0.0, y = 0.0
mutating func moveByX(deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveByX(2.0, y: 3.0)
println("The point is now at (\(somePoint.x), \(somePoint.y))")
// prints "The point is now at (3.0, 4.0)"

The Point structure above defines a variant moveByX method, which moves one instance of Point quantitatively by one. Instead of returning a new starting point, this method actually modifies the point on which the call was made. The mutation contains the definition that is added to it so that it can modify its properties.
Note that you cannot call mutated method structure type constants because its properties cannot be changed, even if they are mutable properties, such as property descriptions stored in fixed structure instances:

 
let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveByX(2.0, y: 3.0)
// this will report an error

The self variation method in distribution
The mutated method can assign an self attribute implied by a completely new instance. The example of the dots shown above can also be written in the following way:


struct Point {
var x = 0.0, y = 0.0
mutating func moveByX(deltaX: Double, y deltaY: Double) {
self = Point(x: x + deltaX, y: y + deltaY)
}
}

This version of the mutant moveByX method creates a completely new structure whose x and y values are set to the target location. The result of calling this method is exactly the same as in the earlier version

The variable method enumeration can be set to self parameter from the same enumeration of different members


enum TriStateSwitch {
case Off, Low, High
mutating func next() {
switch self {
case Off:
self = Low
case Low:
self = High
case High:
self = Off
}
}
}
var ovenLight = TriStateSwitch.Low
ovenLight.next()
// ovenLight is now equal to .High
ovenLight.next()
// ovenLight is now equal to .Off

This example defines a 3-state switch enumeration. Switching cycles between 3 different power states (off, low, high)

2. Type method

As mentioned above, the method of an instance method requires an instance of a specific type. You can also define the type's own method, which is called the type method. The type method you display begins with class func directly inside the class struct. For enums and structures, the type method begins with static func.
Please pay attention to;
In the objective, c, you can define the type-level method to be just the objective, c class. In Swift you can define type-level methods, structures, and enums for all classes. The display of each method is limited to the types it supports.
Type methods call dot syntax, just like instance methods. However, you are calling a method of a type, not an instance of that type. Here's how you call a class to call a method of type 1 of SomeClass:

 
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod()

In the body of a type method, the implied self property refers to the type itself, not an instance of that type. For structs and enumerations, this means that you can disambiguate static properties and static method arguments with self-service, just as you do with instance properties and instance method arguments.

More generally, you will refer to other type-level methods and properties if you use any unqualified method or property name in the body of a method of type 1. A method can call a method of another class with the name of another method without having to be prefixed with the type name. Similarly, struct and enumeration type methods can use the name of a static property without a type name prefix to access the static property.

The following example defines a structure called LevelTracker that tracks a player's progress through different levels or stages of the game. This is a single player game, but can store information for multiple players on a single 1 device.

All game levels (except level 1) when the game is played the first time. Each time a player completes a level, that level unlocks all players on the device. The LevelTracker structure USES static properties and methods to track which levels of play have been unlocked. It also tracks current individual player levels


struct LevelTracker {
static var highestUnlockedLevel = 1
static func unlockLevel(level: Int) {
if level > highestUnlockedLevel {
highestUnlockedLevel = level
}
}
static func levelIsUnlocked(level: Int) -> Bool {
return level <= highestUnlockedLevel
}
var currentLevel = 1
mutating func advanceToLevel(level: Int) -> Bool {
if LevelTracker.levelIsUnlocked(level) {
currentLevel = level
return true
} else {
return false
}
}
}

The LevelTracker structure tracks the highest level of unlock for any player. This value is stored in a static property called highestUnlockedLevel.

LevelTracker also defines two types of functions and highestUnlockedLevel. The first is a function called unlockLevel, which is used to update highestUnlockedLevel every time a new level is unlocked. The second is levelIsUnlocked, which returns ture if a specific level has been unlocked. Note that these types of methods can access the highestUnlockedLevel static property but you need to write it as LevelTracker.highestUnlockedLevel).

In addition to its static properties and type methods, LevelTracker tracks each player's progress through the game. It USES an instance property called currentLevel to track the player level.
To help manage the urrentLevel properties, advanceToLevel LevelTracker defines an instance method. This method updates currentLevel before it is used to check whether the new level required has been unlocked. The advanceToLevel method returns a Boolean value indicating whether it can set currentLevel.
The LevelTracker structure USES the Player class, as shown below, to track and update the progress of individual players:


class Player {
var tracker = LevelTracker()
let playerName: String
func completedLevel(level: Int) {
LevelTracker.unlockLevel(level + 1)
tracker.advanceToLevel(level + 1)
}
init(name: String) {
playerName = name
}
}

The Player class creates a new instance of LevelTracker to track the player's progress. It also provides a method called completedLevel, which unlocks a new level and progress and moves the player to the next level each time a player reaches a specific level. (the Boolean value returned by advanceToLevel is ignored because it is known to be called LevelTracker.unlockLevel.)
You can create an instance of a new player Player to see what happens when a player completes a level:

 
var player = Player(name: "Argyrios")
player.completedLevel(1)
println("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// prints "highest unlocked level is now 2"

If you create a second player and you try to move to a level that has not been unlocked by the game, the current level will fail

 
player = Player(name: "Beto")
if player.tracker.advanceToLevel(6) {
println("player is now on level 6")
} else {
println("level 6 has not yet been unlocked")
}
// prints "level 6 has not yet been unlocked"


Related articles: