0에서 Swift<5> 배우기
구조 함수
구조 함수 기초
구조 함수는 특수한 함수로 대상을 만들 때 초기화하고 대상 구성원 변수에 초기 값을 설정하는 데 사용된다. OC에서 구조 함수는 initWithXXX이다. Swift에서 지원 함수 재부팅으로 모든 구조 함수는 init이다.
구조 함수의 작용
분배 공간 alloc 설정 초기값 init 필수 속성
// Person
class Person: NSObject {
///
var name: String
///
var age: Int
}
알림 오류 Class'Person'has no initializers ->'Person'클래스에 실례화기가 없습니다.
원인: 클래스에 필수 속성이 정의되어 있으면, 구조 함수를 통해 필수 속성에 공간을 분배하고 초기 값을 설정해야 합니다
부류의 구조 함수를 다시 쓰다
/// ` `
override init() {
}
프롬프트 오류 Property'self.name’ not initialized at implicitly generated super.init call -> 속성'self.name'은밀하게 생성된 슈퍼가 없습니다.init 호출 전 초기화
수동으로 슈퍼를 추가합니다.init() 호출////
부모 클래스의 구조 함수 override init () {super.init ()} 오류 프롬프트 Property'self.name’ not initialized at super.init call -> 속성'self.name'은(는) 슈퍼에 없습니다.init 호출 전 초기화비교 선택 속성에 대한 초기값 설정///
부모 클래스의 구조 함수 override init () {name = "장삼"age = 18super.init()
}
소결
비 Optional 속성은 모두 구조 함수에 초기 값을 설정해야 한다. 이로써 대상이 실례화될 때 속성이 모두 정확하게 초기화되어야 한다. 부류 구조 함수를 호출하기 전에 본 종류의 속성이 모두 초기화되었음을 확보해야 한다. Swift의 구조 함수는func 서브클래스의 구조 함수를 쓰지 않아도 된다.
서브클래스를 사용자 정의할 때 구조 함수에서 먼저 본 클래스가 정의한 속성에 초기 값을 설정한 다음에 부류의 구조 함수를 호출하여 부류에서 정의한 속성을 초기화해야 한다
///
class Student: Person {
///
var no: String
override init() {
no = "001"
super.init()
}
}
소결
먼저 이 클래스의 구조 함수를 호출하여 이 클래스의 속성을 초기화한 다음에 부류의 구조 함수를 호출하여 부류의 속성을 초기화한 Xcode 7 beta 5를 호출하면 부류의 구조 함수는 자동으로 호출되므로 슈퍼를 쓰는 것을 강력히 권장합니다.init (), 코드 실행 단서의 가독성을 유지합니다.init () 는 반드시 이 종류의 속성 초기화 뒤에 놓아야 하며, 이 종류의 속성이 모두 초기화되어 Optional 속성이 완성될 것을 보장해야 한다
객체 속성 유형을 Optional로 설정
class Person: NSObject {
///
var name: String?
///
var age: Int?
}
선택 가능한 속성은 초기 값을 설정할 필요가 없습니다. 기본 초기 값은nil 선택 가능한 속성은 수치를 설정할 때만 공간을 분배하는 것입니다. 지연 분배 공간이므로 이동 개발에서 지연 창설의 원칙에 더욱 부합됩니다.
중재 구조 함수
Swift에서 함수 리셋을 지원합니다. 같은 함수 이름, 다른 매개 변수 형식
/// ` `
///
/// - parameter name:
/// - parameter age:
///
/// - returns: Person
init(name: String, age: Int) {
self.name = name
self.age = age
super.init()
}
주의 사항
만약 구조 함수를 다시 불러왔지만 기본 구조 함수 init()가 실현되지 않으면 시스템은 기본 구조 함수 원인을 제공하지 않습니다. 실례화 대상을 할 때 구조 함수를 통해 대상 속성에 대한 분배 공간과 초기 값을 설정해야 합니다. 필수 파라미터가 존재하는 클래스에 대해 기본 init()는 분배 공간과 초기 값을 설정하는 작업을 완성하지 못하고 하위 클래스의 구조 함수를 조정합니다.
부류의 구조 함수를 다시 쓰다
/// ` `
///
/// - parameter name:
/// - parameter age:
///
/// - returns: Student
override init(name: String, age: Int) {
no = "002"
super.init(name: name, age: age)
}
중재 구조 함수
/// ` `
///
/// - parameter name:
/// - parameter age:
/// - parameter no:
///
/// - returns: Student
init(name: String, age: Int, no: String) {
self.no = no
super.init(name: name, age: age)
}
주의: 다시 불러오는 구조 함수라면, 부류 속성의 초기화 작업을 완성하려면 슈퍼가 필요합니다
재부팅 및 재작성
리셋, 함수 이름이 같고 매개 변수 이름/매개 변수 유형/매개 변수 개수가 다른 리셋 함수는 구조 함수 함수 리셋에만 국한된 것이 아니다. 관상 대상 프로그램 설계 언어의 중요한 표지 함수 리셋은 프로그래머의 기억을 간소화할 수 있다. OC는 함수 리셋을 지원하지 않는다. OC의 대체 방식은 withXXX이다. 리셋은 부류가 가지고 있는 방법을 바탕으로 확장해야 하고 오버라이드 키워드가 필요하다.
KVC 사전 회전 모형 구조 함수
/// ` `
///
/// - parameter dict:
///
/// - returns: Person
init(dict: [String: AnyObject]) {
setValuesForKeysWithDictionary(dict)
}
이상의 코드를 컴파일하면 오류가 발생합니다!
이유:
KVC는 OC 특유의 것입니다. KVC는 본질적으로 실행할 때 대상에게 setValue:ForKey:방법을 동적으로 보내고 대상의 속성에 수치를 설정합니다. 따라서 KVC 방법을 사용하기 전에 대상이 정확하게 실례화되었는지 확인해야 합니다.
슈퍼를 추가합니다.init () 역시 오타가 발생할 수 있습니다
이유:
필수 속성은 상위 클래스 구조 함수를 호출하기 전에 초기화 할당 작업을 완료해야 합니다. 필수 매개변수는 다음과 같이 선택적 매개변수로 수정됩니다.
///
class Person: NSObject {
///
var name: String?
///
var age: Int?
/// ` `
///
/// - parameter dict:
///
/// - returns: Person
init(dict: [String: AnyObject]) {
super.init()
setValuesForKeysWithDictionary(dict)
}
}
테스트 실행 중 오류 발생
오류 정보:this class is not key value coding-compliant for the key age. ->이 종류의 키 값age는 키 값 인코딩과 호환되지 않습니다
원인: Swift에서 속성이 선택할 수 있는 경우 초기화할 때 이 속성에 공간을 분배하지 않고 OC에서 기본 데이터 형식은 하나의 수치를 저장하는 것이다. 선택할 수 있는 개념적 해결 방법은 존재하지 않는다. 기본 데이터 형식에 초기 값을 설정하고 수정한 코드는 다음과 같다.
///
var name: String?
///
var age: Int? = 0
/// ` `
///
/// - parameter dict:
///
/// - returns: Person
init(dict: [String: AnyObject]) {
super.init()
setValuesForKeysWithDictionary(dict)
}
알림: 클래스를 정의할 때 기본 데이터 형식 속성은 반드시 초기 값을 설정해야 합니다. 그렇지 않으면 KVC로 값을 설정할 수 없습니다
KVC 함수 호출 순서
init(dict: [String: AnyObject]) {
super.init()
setValuesForKeysWithDictionary(dict)
}
override func setValue(value: AnyObject?, forKey key: String) {
print("Key \(key) \(value)")
super.setValue(value, forKey: key)
}
// `NSObject` , `NSUndefinedKeyException`
override func setValue(value: AnyObject?, forUndefinedKey key: String) {
print("UndefinedKey \(key) \(value)")
}
setValuesForKeysWithDictionary는 사전의 키에 따라 setValue:forKey 함수를 반복적으로 호출합니다.forUndefinedKey 함수가 실현되지 않으면 프로그램은 직접 붕괴됩니다.NSObject는 기본적으로 정의되지 않은 키 값을 발견할 때 NSUndefinedKey Exception 이상을 던집니다.forUndefinedKey가 실현되면 setValuesForKeysWithDictionary가 후속 키를 계속 훑어보며 부모류가 fordefinedKey를 실현한다면하위 클래스는 이 함수 하위 클래스의 KVC 함수를 구현하지 않아도 됩니다.
///
class Student: Person {
///
var no: String?
}
만약 부류에서 부류와 관련된 방법을 실현했다면, 자류에서는 관련 방법을 다시 실현할 필요가 없다
최근에야 github에 뭘 넣기 시작했는데 회사에서는 못 넣는다고 썼어요.
github 주소:https://github.com/FuThD
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.