singletonInstance
переменная является набор для nil
, а потому, что он имеет static
сферу (т.е. он ведет себя как глобальный, который доступен только в рамках этого метода), он устанавливается в nil
только один раз (не каждый время, которое этот метод называется). Итак, как только singletonInstance
установлен в конкретный экземпляр этого класса внутри блока dispatch_once
, вы можете быть уверены, что переменная не будет сброшена на nil
позже.
Звонок dispatch_once
просто гарантирует, что блок кода вызывается один раз и только один раз (и переменная static
, onceToken
, является тем, как она отслеживает, была ли она еще вызвана). Преимущество шаблона dispatch_once
, в отличие от других подходов, заключается в том, что он потокобезопасен (поэтому, даже если несколько потоков пытаются одновременно вызвать singletonInstance
, он будет вызван только один раз, избегая условий гонки).
Общей проблемой здесь является использование ключевого слова static
в объявлениях переменных. Квалификатор static
указывает, что переменная не является локальной переменной, уникальной для конкретного метода, и не является переменной экземпляра, уникальной для конкретного экземпляра класса. Это переменная, которая эффективно распределяется между всеми вызовами этого метода singletonInstance
(или, по крайней мере, до тех пор, пока приложение не будет завершено). Таким образом, переменные static
являются эффективным механизмом для отслеживания экземпляра singleton, а также хорошей ссылкой, которую dispatch_once
может использовать для отслеживания того, был ли он вызван или нет.