클래스의 인스턴스는 전통적으로 객체로 알려져 있습니다. 그러나 Swift 구조체와 클래스는 다른 언어보다 기능면에서 훨씬 더 가깝고 이 장의 대부분은 클래스 또는 구조체 유형의 인스턴스에 적용되는 기능에 대해 설명합니다. 이 때문에 보다 일반적인 용어 인스턴스가 사용됩니다.
클래스와 액터는 동일한 특성과 동작을 많이 공유합니다. 행위자에 대한 정보는 동시성을 참조하십시오.
struct SomeStructure {
// structure definition goes here
}
class SomeClass {
// class definition goes here
}
새 구조체나 클래스를 정의할 때마다 새 Swift 유형을 정의합니다. 표준 Swift 유형(예: String, Int 및 Bool)의 대문자 사용과 일치하도록 유형에 UpperCamelCase 이름(예: SomeStructure 및 SomeClass)을 지정합니다.속성 및 메서드에 lowerCamelCase 이름(예: frameRate 및 incrementCount)을 지정하여 유형 이름과 구별합니다.
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
let someResolution = Resolution()
let someVideoMode = VideoMode()
print("The width of someResolution is \(someResolution.width)")
// Prints "The width of someResolution is 0"
print("The width of someVideoMode is \(someVideoMode.resolution.width)")
// Prints "The width of someVideoMode is 0"
someVideoMode.resolution.width = 1280
print("The width of someVideoMode is now \(someVideoMode.resolution.width)")
// Prints "The width of someVideoMode is now 1280"
let vga = Resolution(width: 640, height: 480)
값 유형은 변수나 상수에 할당되거나 함수에 전달될 때 값이 복사되는 유형입니다.
사실, Swift의 모든 기본 유형(정수, 부동 소수점 숫자, 부울, 문자열, 배열 및 사전)은 값 유형이며 배후에서 구조체로 구현됩니다.
모든 구조체와 열거형은 Swift의 값 유형입니다. 즉, 생성한 모든 구조체 및 열거형 인스턴스와 속성으로 포함된 모든 값 유형은 코드에서 전달될 때 항상 복사됩니다.
배열, 사전 및 문자열과 같은 표준 라이브러리에 의해 정의된 컬렉션은 최적화를 사용하여 복사의 성능 비용을 줄입니다. 즉시 복사본을 만드는 대신 이러한 컬렉션은 원본 인스턴스와 복사본 간에 요소가 저장되는 메모리를 공유합니다. 컬렉션 복사본 중 하나가 수정되면 수정 직전에 요소가 복사됩니다. 코드에서 볼 수 있는 동작은 항상 복사가 즉시 발생한 것처럼 보입니다.
이전 예의 Resolution 구조체를 사용하는 다음 예를 고려하십시오.
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
이 예제는 hd라는 상수를 선언하고 풀 HD 비디오(폭 1920픽셀 x 높이 1080픽셀)의 너비와 높이로 초기화된 Resolution 인스턴스로 설정합니다.
그런 다음 시네마라는 변수를 선언하고 HD의 현재 값으로 설정합니다.
Resolution은 구조체이기 때문에 기존 인스턴스의 복사본이 만들어지고 이 새 복사본이 영화관에 할당됩니다.
이제 HD와 시네마의 너비와 높이가 동일하지만 장면 뒤에서 완전히 다른 두 인스턴스입니다.
다음으로, 시네마의 너비 속성은 디지털 시네마 프로젝션에 사용되는 약간 더 넓은 2K 표준의 너비로 수정됩니다(2048픽셀 너비 및 1080픽셀 높이)
cinema.width = 2048
Cinema의 width 속성을 확인하면 실제로 2048로 변경되었음을 알 수 있습니다.
print("cinema is now \(cinema.width) pixels wide")
// Prints "cinema is now 2048 pixels wide"
그러나 원래 hd 인스턴스의 너비 속성에는 여전히 1920의 이전 값이 있습니다.
print("hd is still \(hd.width) pixels wide")
// Prints "hd is still 1920 pixels wide"
시네마에 현재 HD 값이 주어지면 hd에 저장된 값이 새 시네마 인스턴스에 복사됩니다.
최종 결과는 동일한 숫자 값을 포함하는 완전히 별개의 두 인스턴스였습니다.
그러나 별개의 인스턴스이기 때문에 아래 그림과 같이 시네마 너비를 2048로 설정해도 hd에 저장된 너비에는 영향을 미치지 않습니다.
열거형에도 동일한 동작이 적용됩니다.
enum CompassPoint {
case north, south, east, west
mutating func turnNorth() {
self = .north
}
}
var currentDirection = CompassPoint.west
let rememberedDirection = currentDirection
currentDirection.turnNorth()
print("The current direction is \(currentDirection)")
print("The remembered direction is \(rememberedDirection)")
// Prints "The current direction is north"
// Prints "The remembered direction is west"
storedDirection에 currentDirection 값이 할당되면 실제로 해당 값의 복사본으로 설정됩니다.
그 이후에 currentDirection의 값을 변경해도 RememberDirection에 저장된 원래 값의 복사본에는 영향을 미치지 않습니다.
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// Prints "The frameRate property of tenEighty is now 30.0"
if tenEighty === alsoTenEighty {
print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")
}
// Prints "tenEighty and alsoTenEighty refer to the same VideoMode instance."