Объявление не может быть как "окончательной", так и "динамической" ошибкой в Swift 1.2


декларация value ниже

import Foundation

class AAA: NSObject {
    func test2() {
        self.dynamicType
    }
}
extension AAA {
    static let value    =   111
}

вызывает следующую ошибку компиляции

A declaration cannot be both 'final' and 'dynamic'

почему это происходит, и как мне бороться с этим?

Я использую Swift 1.2 (версия поставляется в Xcode 6.3.1 6D1002)

7 121

7 ответов:

эта проблема возникает потому, что Swift пытается создать динамический метод доступа для статического свойства для совместимости Obj-C, так как класс наследует от NSObject.

если ваш проект находится только в Swift, а не с помощью var accessor вы можете избежать этой проблемы через @nonobjc атрибут в Swift 2.0:

import Foundation

class AAA: NSObject {}
extension AAA {
    @nonobjc static let value = 111
}

вы получите эту ошибку, если ваш класс удовлетворяет этим условиям.

  • от NSObject.
  • есть

У меня тоже была эта ошибка.

моя проблема была просто статический var в быстром расширении.

extension NotificationsViewController: UITableViewDataSource , UITableViewDelegate {

    static var timeIntervalFormatter = NSDateComponentsFormatter()

}

перемещение его в реализацию класса решило проблему для меня.

Я просто наткнулся на ту же проблему с другой причиной и хотел бы разместить его здесь для других людей, испытывающих те же бесполезное сообщение об ошибке.

окончательный класс, который переопределяет вычисляемую переменную, определенную в расширении, также вызывает эту ошибку. Это работает для функций и, таким образом, выглядит как ошибка компилятора.

// at line 0: a declaration cannot be both 'final' and 'dynamic'

import UIKit

extension UIViewController {
    var test: Int { return 0 }
}

final class TestController: UIViewController {
    override var test: Int { return 1 }
}

Я решил эту проблему, переместив статическое объявление в новую структуру, которую я определил в расширении.

Так вместо этого:

extension NSOperationQueue {
    static var parsingQueue : NSOperationQueue = {
        let queue = NSOperationQueue()
        queue.maxConcurrentOperationCount = 1
        return queue
        }()
}

у меня есть это:

extension NSOperationQueue {        
    struct Shared {
        static var parsingQueue : NSOperationQueue = {
            let queue = NSOperationQueue()
            queue.maxConcurrentOperationCount = 1
            return queue                
            }()
    }
}

вы можете пометить его как частный, чтобы предотвратить эту ошибку. Если вы хотите выставить его, вы можете обернуть его в публичную функцию:

extension AAA {

    private static let value = 111

    public func getDatValue() -> Int {
        return AAA.value
    }    
}

в моем случае я только ссылался на свойство в самом расширении, поэтому не было необходимости его выставлять.

как небольшое улучшение по сравнению с @Eonil это на get Не надо:

static var value: Int { return  111 }