Змінні класу ще не підтримуються


93

Я починаю свій проект з контролера розділеного перегляду як початкового контролера перегляду і запускаю його автоматично з розкадрівки.

Як правило, програма з цим інтерфейсом має один і лише один контролер розділеного подання як кореневий, тому я створюю статичну змінну в підкласі і встановлюю її, коли було виконано ініціалізацію.

Тому я хочу спробувати цю поведінку швидко.

Я прочитав довідник мови мови програмування Swift на iBook про властивості Type (із ключовим словом static і class) і намагався виконати шматок коду на роботі:

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

Це призводить до тієї ж помилки.
Цезар

1
Це перше насіння, заспокойся. :) Якщо книга каже, що вона підтримується і вона ще не доступна, вона буде . Навіть помилка говорить «поки» .
акашівський

1
Так @akashivskyy Ви маєте причину, але може бути, це могло бути і помилка з мого боку, і хтось має рішення зробити таку поведінку ...
Vincent 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
Як каже Білл, це не те саме, але це мені потрібно!
Вінсент Салуццо,

@VincentSaluzzo, (та Білл) Яка різниця між цією змінною класу?
підневільний

Документація Apple нещодавно змінилася, щоб оновити статус: developer.apple.com/library/ios/documentation/Swift/Conceptual/ ... Насправді classключове слово зараз може використовуватися лише для обчислюваних властивостей, а статичне - для всіх властивостей типу (у enum, class або структура)
Вінсент Салуцо

@skywinder Як я вже згадував у своїй відповіді, змінні справжніх класів можуть бути успадковані підкласами. Статичні змінні не можуть.
Білл

@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
Працювало для мене - за винятком випадків, коли мені довелося відмовитися від "public", оскільки XCode 6.0 не любив мене оголошувати публічним класом у внутрішньому класі.
Алі Бідл

Працює чудово, за винятком того, що xcode не дозволяє вкладеному типу в загальний тип ... тому, якщо у вас є загальний клас, це здається досить безнадійним, оскільки можливі лише обчислювані властивості.
BenMQ

19

Здається, можна оголосити змінні зі статичною тривалістю зберігання в області файлу (як на C):

var sharedInstance: SplitViewController? = nil

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

mmmh, чому б ні, але визначення var в області файлу не витікає пам'ять за тривалого використання?
Вінсент Салуццо

@VincentSaluzzo Немає різниці у тому, що ви робили перед Swift: зберігайте єдиний екземпляр у статичній змінній. Тут нічого не може просочитися, крім одиничного екземпляра, який триває доти, доки процес.
Микола Руе

Я спробував це на дитячому майданчику з власним класом. Це не працює, оскільки клас ще не був оголошений, коли ви ініціалізували цей "статичний" вар. Я не пробував цього в проекті Xcode (я думаю, він, мабуть, там працював?). Тому мені може знадобитися з'ясувати "переадресацію класу", як ви завжди робите, коли вказуєте протокол для класу.
kawingkelvin

2
Зауважте, що в Xcode 6.0 ви не можете мати дві змінні області файлу з тим самим іменем, навіть якщо вони є private.
nschum

@NikolayTsenkov Рівно.
Микола Рухе

14

Моїм кращим методом є просто використовувати приватну область файлу var за межами класу, а потім реалізувати класові / статичні геттери та сеттери:

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для класів)?
Кріс Коновер

@chrisco У примітках до випуску зазначено, що staticце псевдонім class final.
Андреас Лей


4

Рішення, достатньо схоже на var в області файлу, але більш настроюється і поблизу singleton - використовувати структуру, яка підтримує статичний 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

Гаразд, з рішенням Миколи, які роблять роботу. Я публікую свої зміни в цій темі для інформації

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

Мені просто цікаво, але чи не змінна "екземпляр" є глобальною змінною тоді? Це означало б, що якщо у вас є інший клас-синглтон, ваша змінна "екземпляр" буде перезаписана, так?
Рафаель

1

Формулювання помилки в значній мірі означає, що це буде мовна особливість у майбутньому.

Можливо, ви хочете тимчасово вдатися до оголошення змінної властивості в Делегуванні програм і отримати її звідти. Не ідеально, безумовно, анти-візерунок, але дасть вам центральне місце для пошуку, UISplitViewControllerколи потрібно.


Ні тому, що в моєму випадку SplitViewController був ініціалізований під час виконання, коли прокинувся із аркуша розкадрування, тому я не можу безпосередньо отримати доступ до цього контролера подання даних від мого делегата програми
Вінсента Салуццо

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

Він називається " Властивість типу" у Swift.

Ви визначаєте властивості типу за допомогою статичного ключового слова. Для обчислюваних властивостей типу для типів класів замість цього можна використовувати ключове слово 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.