아직 지원되지 않는 클래스 변수


93

분할보기 컨트롤러를 초기보기 컨트롤러로 사용하여 프로젝트를 시작하고 스토리 보드에서 자동으로 시작합니다.

일반적으로이 UI를 사용하는 앱에는 루트로 분할보기 컨트롤러 가 하나만 있으므로 하위 클래스에 정적 변수 를 만들고 초기화가 완료 될 때 설정합니다.

그래서 나는이 행동을 신속하게 시도하고 싶습니다.

유형 속성 (정적 및 클래스 키워드 포함)에 대한 iBook의 Swift 프로그래밍 언어 가이드 북을 읽고 작업에 대한 코드를 시도했습니다.

import UIKit

class SplitViewController: UISplitViewController {

    class func sharedInstance() -> SplitViewController {
        return SplitViewController.instance
    }

    class let instance: SplitViewController = nil

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        self.initialization()
    }

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder);
        self.initialization()
    }

    func initialization() {
        SplitViewController.instance = self;
    }
}

그러나 Xcode가 유형 속성에 대한 클래스 키워드가 아직 지원되지 않는다고 말할 때 알아 냈습니다.

이미지의 오류 세부 정보

이 작업을 수행 할 솔루션이 있습니까?


'let'을 'var'로 바꾸면 어떻게됩니까?
ZunTzu 2014-06-03

동일한 오류가 발생합니다.
Cezar

1
첫 번째 씨앗입니다. 진정하세요. 이 책이 지원 그리고 아직 사용할 수없는 말한다면 :), 그것은 것입니다 합니다. 오류에도 "아직"이라고 표시 됩니다.
akashivskyy 2014-06-03

1
예 @akashivskyy 당신은 ... 이유를했습니다 그러나이 될 수있을 수 있으며, 내 옆에 누군가에 오류가이 동작을 할 수있는 해결책을 가지고 있습니다
빈센트 Saluzzo의

1
@lespommes Apple은 보류중인 모든 것에 대해 꽉 찬 입으로 악명 높습니다. 새로운 주력 언어의 대규모 출시로 인해 그러한 표준적이고 명백한 기능이 부족하다는 것은 당혹 스럽습니다. Swift가 진지하게 사용되기 전에 많은 개선이 필요합니다.
Hyperbole

답변:


37

Swift는 이제 클래스에서 정적 변수를 지원합니다. 이것은 클래스 변수와 정확히 같지는 않지만 (하위 클래스에 의해 상속되지 않기 때문에), 꽤 가깝습니다.

class X {
  static let y: Int = 4
  static var x: Int = 4
}

println(X.x)
println(X.y)

X.x = 5

println(X.x)

1
Bill이 말했듯이, 그것은 동일하지 않지만 내가 필요합니다!
Vincent Saluzzo

@VincentSaluzzo, (그리고 Bill)이 변수와 클래스 변수의 차이점은 무엇입니까?
skywinder

Apple 문서는 최근 상태를 업데이트하기 위해 변경되었습니다. developer.apple.com/library/ios/documentation/Swift/Conceptual/… 실제로 class키워드는 현재 계산 된 속성에만 사용할 수 있으며 static은 모든 유형 속성 (enum, class 또는 struct)
Vincent Saluzzo

@skywinder 내 대답에서 언급했듯이 진정한 클래스 변수는 하위 클래스에 상속 될 수 있습니다. 정적 변수는 할 수 없습니다.
Bill

@VincentSaluzzo Apple이 문서를 업데이트합니까? developer.apple.com/library/ios/documentation/Swift/Conceptual/… 네 번째 단락을보십시오. "값 유형 (즉, 구조 및 열거 형)의 경우 저장 및 계산 된 유형 속성을 정의 할 수 있습니다. 클래스의 경우 다음을 수행 할 수 있습니다. 계산 된 유형 속성 만 정의합니다. "
fujianjin6471

73

구조체 포함은 해결 방법으로 잘 작동 할 수 있습니다.

class SomeClass
{
  // class var classVariable: Int = 0
  // "Class variables not yet supported." Weird.

  // Workaround:
  private struct SubStruct { static var staticVariable: Int = 0 }

  class var workaroundClassVariable: Int
  {
    get { return SubStruct.staticVariable }
    set { SubStruct.staticVariable = newValue }
  }
}

SomeClass.workaroundClassVariable 계산 된 유형 속성은 저장된 유형 속성 인 것처럼 사용할 수 있습니다.


1
나를 위해 일했습니다-XCode 6.0이 내부 클래스 내에서 공용 클래스를 선언하는 것을 좋아하지 않았기 때문에 '공개'를 삭제해야한다는 점을 제외하고는.
Ali Beadle 2014 년

xcode가 제네릭 유형에 중첩 유형을 허용하지 않는다는 점을 제외하면 훌륭하게 작동합니다. 따라서 제네릭 클래스가있는 경우 계산 된 속성 만 가능하기 때문에 다소 절망적입니다.
BenMQ

19

파일 범위 (C에서와 같이)에서 정적 저장 기간으로 변수를 선언 할 수있는 것 같습니다.

var sharedInstance: SplitViewController? = nil

class SplitViewController: UISplitViewController {
    ....
    func initialization() {
        sharedInstance = self
    }
}

mmmh, 왜 안되지만 파일 범위에서 var를 정의하면 오랜 시간 동안 메모리 누수가 발생하지 않습니까?
Vincent Saluzzo

@VincentSaluzzo Swift 이전에했던 것과는 차이가 없습니다. 정적 변수에 유일한 인스턴스를 저장합니다. 프로세스만큼 오래 살아가는 단일 인스턴스를 제외하고는 여기에 유출 될 것이 없습니다.
Nikolai Ruhe

나는 내 수업과 함께 놀이터에서 이것을 시도했습니다. '정적'var를 초기화 할 때 클래스가 아직 선언되지 않았기 때문에 작동하지 않습니다. 나는 Xcode 프로젝트에서 그것을 시도하지 않았습니다 (나는 거기에서 작동했을 것 같습니까?). 따라서 클래스에 대한 프로토콜을 지정할 때 항상하는 것처럼 "클래스 전달 선언"을 파악해야 할 수도 있습니다.
kawingkelvin 2014 년

2
Xcode 6.0에서는 동일한 이름을 가진 두 개의 파일 범위 변수를 가질 수 없습니다 private.
nschum 2014 년

@NikolayTsenkov 맞습니다.
Nikolai Ruhe 2014 년

14

내가 선호하는 방법은 클래스 외부에서 개인 파일 범위 var를 사용한 다음 클래스 / 정적 getter 및 setter를 구현하는 것입니다.

private var _classVar: Int = 0;

class SomeClass
{
    public class var classVar: Int
    {
        get { return _classVar }
        set { _classVar = newValue }
    }
}

5

Swift 1.2 (Xcode 6.3b1 이상에서 사용 가능)부터 static클래스 속성 및 메서드가 지원됩니다.

class SomeClass
{
    static var someVariable: Int = 0
}

1
방금 class변수를 사용하지 않는지 파악 했습니까? 아니면 구별이 있습니까 ( static구조물, class클래스에 사용됨 )?
Chris Conover 2015 년

@chrisco 릴리스 정보 static에는 class final.
Andreas Ley 2015 년


4

파일 범위에서 var와 충분히 유사하지만 사용자 정의가 가능하고 단일에 가까운 해결책은 정적 var를 클래스의 속성으로 지원하는 구조체를 사용하는 것입니다.

struct PersonSharedData {
    static var backstore = ""
    var data: String {
    get { return PersonSharedData.backstore }
    set { PersonSharedData.backstore = newValue }
    }
}

class Person {
    var shared=PersonSharedData() //<< pseudo class var
    var family: String {
        get { return shared.data }
        set { shared.data=newValue }
    }
    var firstname = ""
    var lastname = ""
    var sexe: Sexe = .Unknown
}

2

좋아, 작업을 수행하는 Nikolai의 솔루션으로. 정보를 위해이 스레드에 변경 사항을 게시합니다.

var instance: SplitViewController? = nil

class SplitViewController: UISplitViewController {

    class func sharedInstance() -> SplitViewController? {
        return instance;
    }

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        self.initialization()
    }

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder);
        self.initialization()
    }

    func initialization() {
        instance = self
    }
}

예를 들어, 내 appDelegate에서 다음과 같이이 정적 메서드에 액세스 할 수 있습니다.

SplitViewController.sharedInstance()!.presentsWithGesture = false

그냥 궁금한데 "인스턴스"변수가 전역 변수가 아닌가? 이것은 만약 당신이 다른 싱글 톤 클래스를 가지고 있다면 당신의 변수 "인스턴스"를 덮어 쓸 것이라는 것을 의미 할 것입니다. 그렇죠?
Raphael 2014

1

오류의 문구는 이것이 향후 언어 기능이 될 것임을 의미합니다.

일시적으로 Application Delegate에서 속성 변수를 선언하고 거기에서 검색 할 수 있습니다. 이상적이지 않고 확실히 안티 패턴이지만 UISplitViewController필요할 때 검색 할 수있는 중앙 위치를 제공 합니다.


내 경우, SplitViewController는 런타임에 의해 initizalize, 스토리 보드에서 깨어 때 없었다 없음 때문에 그래서 내가 할 수있는 내 응용 프로그램 위임에서이 뷰 컨트롤러에 직접적으로 접근
빈센트 Saluzzo의

1

내부 구조체 변수 안에 클래스 변수를 래핑해야합니다.

class Store{
    var name:String
    var address:String
    var lat:Int
    var long:Int
    init(name:String, address:String, lat:Int, long:Int){
        self.name = name
        self.address = address
        self.lat = lat
        self.long=long
    }

    private struct FACTORY_INITIALIZED_FLAG { static var initialized: Bool = false
       static var  myStoreList:[Store]?
        static func getMyStoreList()->[Store]{
            if !initialized{
                println("INITIALIZING")
                myStoreList = [
                    Store(name: "Walmart", address: "abcd", lat: 10, long: 20),
                    Store(name: "JCPenny", address: "kjfnv", lat: 23, long: 34)
                ]
                initialized = true
            }
                return myStoreList!
    }
    }
}


var a = Store.FACTORY_INITIALIZED_FLAG.getMyStoreList()

var b = Store.FACTORY_INITIALIZED_FLAG.getMyStoreList()

// only prints INITIALIZING once

0

이 시도:

class var instance: SplitViewController {
    return nil
}

0

Swift 에서는 Type Property 라고 합니다.

static 키워드로 유형 속성을 정의합니다. 클래스 유형에 대한 계산 된 유형 속성의 경우 대신 class 키워드를 사용하여 하위 클래스가 수퍼 클래스의 구현을 재정의 할 수 있습니다. 아래 예는 저장 및 계산 된 유형 속성의 구문을 보여줍니다.

struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 1
    }
}
enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 6
    }
}
class SomeClass {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
    class var overrideableComputedTypeProperty: Int {
        return 107
    }
}

아래 링크에서 자세히 알아보십시오.

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-ID254

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.