development

Swift의 클래스에 대한 "초기화"클래스 메소드?

big-blog 2020. 10. 24. 11:08
반응형

Swift의 클래스에 대한 "초기화"클래스 메소드?


Objective-C의 +(void)initialize클래스 메서드 와 유사한 동작을 찾고 있는데 ,이 메서드는 클래스가 초기화 될 때 한 번 호출되고 이후에는 다시는 호출되지 않습니다.

간단한 class init () {}A의 class폐쇄는 정말 세련된 것! 그리고 분명히 우리가 class var" static vars in a struct Closure" 대신 " s" 를 사용하게되면 , 이것은 모두 정말 잘 일치 할 것입니다!


Objective-C 클래스가있는 경우를 재정의하는 것이 가장 쉽습니다 +initialize. 그러나 클래스하위 클래스도 재정의 +initialize해야합니다. 그렇지 않으면 클래스가 +initialize두 번 이상 호출 될 수 있습니다. 원하는 경우 dispatch_once()(아래 언급 됨)을 사용 하여 여러 통화로부터 보호 할 수 있습니다 .

class MyView : UIView {
  override class func initialize () {
    // Do stuff
  }
}

 

Swift 클래스가있는 경우 얻을 수있는 최선의 방법 dispatch_once()init()내부 입니다.

private var once = dispatch_once_t()

class MyObject {
  init () {
    dispatch_once(&once) {
      // Do stuff
    }
  }
}

이 솔루션은 +initialize(Objective-C 클래스가 처음으로 메시지를받을 때 호출 됨) 과 다르 므로 질문에 대한 진정한 대답이 아닙니다. 하지만 충분히 잘 작동합니다, IMO.


Swift 에는 유형 이니셜 라이저 가 없습니다 .

“저장된 ​​인스턴스 속성과 달리 항상 저장된 유형 속성에 기본값을 제공해야합니다. 이는 타입 자체에는 초기화시에 저장된 타입 속성에 값을 할당 할 수 있는 이니셜 라이저 가 없기 때문 입니다.”

발췌 : Apple Inc.“The Swift Programming Language.” iBooks .


기본값이 클로저 인 유형 속성사용할 수 있습니다 . 따라서 클로저의 코드는 유형 속성 (또는 클래스 변수)이 설정 될 때 실행됩니다 .

class FirstClass {
    class var someProperty = {
     // you can init the class member with anything you like or perform any code
        return SomeType
    }()
}

그러나 class stored properties not yet supported(Xcode 8에서 테스트 됨).

한 가지 대답은 사용하는 static것입니다 class final.

그것에 대한 좋은 링크는

클로저 또는 함수를 사용하여 기본 속성 값 설정

발췌 : Apple Inc.“The Swift Programming Language.” iBooks .


코드 예 :

class FirstClass {
    static let someProperty = {
        () -> [Bool] in
        var temporaryBoard = [Bool]()
        var isBlack = false
        for i in 1...8 {
            for j in 1...8 {
                temporaryBoard.append(isBlack)
                isBlack = !isBlack
            }
            isBlack = !isBlack
        }

        print("setting default property value with a closure")
        return temporaryBoard
    }()
}

print("start")
FirstClass.someProperty

인쇄물

스타트

클로저로 기본 속성 값 설정

그래서 그것은 게으른 평가입니다.


의 경우 @objc클래스, class func initialize()이후 확실히 작동 +initialize목적-C 런타임에 의해 구현됩니다. 그러나 "기본"Swift 클래스의 경우 다른 답변을 확인해야합니다.


@aleclarson이 못 박았지만 최근 Swift 4에서는 initialize. Objective-C 및 다음 과 함께 컴파일 소스에 포함하는 에서 Objective-C에서 호출되는 NSObject클래스 / 정적 swiftyInitialize메서드 사용하여 상속되는 클래스에 대한 범주로이를 달성 할 수 있습니다 .MyClass.mMyClass.swift

# MyView.swift

import Foundation
public class MyView: UIView
{
    @objc public static func swiftyInitialize() {
        Swift.print("Rock 'n' roll!")
    }
}

# MyView.m

#import "MyProject-Swift.h"
@implementation MyView (private)
    + (void)initialize { [self swiftyInitialize]; }
@end

클래스에서 상속 할 수없고 대신 NSObject사용 +load하는 +initialize것이 적합한 경우 다음과 같이 할 수 있습니다.

# MyClass.swift

import Foundation
public class MyClass
{
    public static func load() {
        Swift.print("Rock 'n' roll!")
    }
}
public class MyClassObjC: NSObject
{
    @objc public static func swiftyLoad() {
        MyClass.load()
    }
}

# MyClass.m

#import "MyProject-Swift.h"
@implementation MyClassObjC (private)
    + (void)load { [self swiftyLoad]; }
@end

특히 정적 라이브러리에서이 접근 방식을 사용할 때 몇 가지 문제가 있습니다 . 자세한 내용은 Medium 의 전체 게시물확인 하세요! ✌️


initialize메소드 대신 저장된 유형 속성을 사용할 수 있습니다 .

class SomeClass: {
  private static let initializer: Void = {
    //some initialization
  }()
}

But since stored types properties are actually lazily initialized on their first access, you will need refer them somewhere. You can do this with ordinary stored property:

class SomeClass: {
  private static let initializer: Void = {
    //some initialization
  }()
  private let initializer: Void = SomeClass.initializer
}

I can't find any valid use case to have something like +[initialize] in Swift. Maybe this explains way it does not exist

Why do we need +[initialize] in ObjC?

To initialize some global variable

static NSArray *array;

+ (void)initialize {
    array = @[1,2,3];
}

which in Swift

struct Foo {
    static let array = [1,2,3]
}

To do some hack

+ (void)initialize {
    swizzle_methodImplementation()
}

which is not supported by Swift (I can't figure out how to do it for pure Swift class/struct/enum)

참고URL : https://stackoverflow.com/questions/24137212/initialize-class-method-for-classes-in-swift

반응형