2016-04-26 2 views
5

У меня есть struct установить, что принимает ссылку в качестве единственного параметра инициализации:Ссылка `self` в объявлении члена Swift экземпляра

internal struct NodeState: Equatable { 
    weak var node: Node! = nil 
    // ... 

    init(node: Node) { 
     self.node = node 
    } 
} 

Я хочу, чтобы создать экземпляр NodeState в качестве члена Node класса, передавая self, чтобы установить, что слабая ссылка:

public class Node: NSObject { 
    internal var state = NodeState(node: self) 
    // ... 
} 

... но я получаю эту странную ошибку компиляции:

Cannot convert value of type 'NSObject ->() -> Node' to expected argument type 'Node'

Мне не позволено ссылаться на self в декларации участника в Свифт?

+0

Возможный дубликат [Инициализация Swift свойства, которые требуют «я» в качестве аргумента] (http://stackoverflow.com/questions/25149248/initializing-swift-properties-that-require-self -as-an-argument) – jtbandes

+0

Просто отметим, что странная ошибка компиляции связана с [методом 'self' в NSObject] (https://developer.apple.com/reference/objectivec/nsobjectprotocol/1418954-self). В классе, отличном от ObjC, ошибка будет просто «Использовать разрешенный идентификатор« self ». – kennytm

ответ

2

В целом вы не можете ссылаться на self в декларации класса участников, но можете, если вы сделаете свойство ленивым и инициализируете его закрытием. Изменение Node класса к чему-то, как это должно работать:

public class Node: NSObject { 
    internal lazy var staticState: NodeState = { NodeState(node: self) }() 
} 

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

+0

Я получаю точно такую ​​же ошибку. :(Кажется, что-то связано с нарушением типа. – devios1

+0

Он компилируется для меня без ошибок. Какую версию Xcode вы используете? –

+1

А, у меня плохое, отсутствует явное объявление типа для staticState. – devios1

1

Ссылка self в закрытии?

public class Node: NSObject { 

    lazy var staticState:() -> (NodeState) = { 
     [unowned self] in 
     return NodeState(node: self) 

    } 
} 

Я явно декорирования self как unowned в крышке, чтобы не допустить сохранения цикла.

+0

Just заметили, что не так! Ваша ленивая переменная здесь определяется как тип закрытия, а не тип экземпляра 'NodeState' (который я не уверен, что хочет OP). Поэтому без' [unowned self] 'он действительно создаст удержание Если вы измените объявление на тип экземпляра 'NodeState' с закрытием автоматического выполнения (как показано в принятом ответе),' [unowned self] 'не требуется, поскольку Swift достаточно умен, чтобы избежать цикла сохранения в этом Случай – Hamish

+0

Правильно. Это не «неправильно», это просто другая реализация (а не автоматическое завершение закрытия). – JAL

+0

Когда я сказал «неправильно», я имел в виду, что было не так с моим оригинальным комментарием (о '[unowned self ] 'не будучи требуется) - не оспаривая правильность вашего ответа. – Hamish

2

Am I not allowed to reference self in a member declaration in Swift?

Сорт. Вы не можете ссылаться на self (например, на вызов методов, передавая себя как параметр), пока объект не будет полностью инициализирован.

В этом случае вы можете использовать ленивый var, который будет работать, поскольку он не может быть доступен, пока объект не будет инициализирован. Вот пример:

public class Node: NSObject { 
    internal lazy var staticState: NodeState = { 
     return NodeState(node: self) 
    }() 
} 
Смежные вопросы