почему apple рекомендует использовать dispatch\_once для реализации одноэлементного шаблона в arc?

<p>какова точная причина использования dispatch\_once в средстве доступа к экземпляру единого экземпляра в arc?</p><pre><code>+ (myclass *)sharedinstance { // static local predicate must be initialized to 0 static myclass *sharedinstance = nil; static dispatch\_once\_t oncetoken = 0; dispatch\_once(&oncetoken, ^{ sharedinstance = [[myclass alloc] init]; // do any other initialisation stuff here }); return sharedinstance; } </code></pre><p>разве это не плохая идея - создать экземпляр singleton асинхронно в фоновом режиме? я имею в виду, что произойдет, если я запрашиваю этот общий экземпляр и сразу полагаюсь на него, но dispatch\_once требуется до рождества для создания моего объекта? не сразу возвращается, верно? по крайней мере, в этом и заключается весь смысл grand central dispatch.</p><p>так почему они это делают?</p>

<p><code>dispatch\_once()</code> абсолютно синхронный. не все методы gcd делают вещи асинхронно (в данном случае <code>dispatch\_sync()</code> синхронна). использование <code>dispatch\_once()</code> заменяет следующую идиому:</p><pre><code>+ (myclass *)sharedinstance { static myclass *sharedinstance; @synchronized(self) { if (sharedinstance == nil) { sharedinstance = [[myclass alloc] init]; } } return sharedinstance; } </code></pre><p>преимущество <code>dispatch\_once()</code> в этом заключается в том, что это быстрее. это также семантически чище, потому что оно также защищает вас от нескольких потоков, выполняющих alloc init вашего sharedinstance - если они все пытаются в одно и то же время. это не позволит создать два экземпляра. вся идея <code>dispatch\_once()</code> заключается в том, чтобы "выполнить что-то один раз и только один раз", и именно это мы и делаем.</p>

<p>потому что он будет работать только один раз. так что если вы попытаетесь получить к нему доступ дважды из разных потоков, это не вызовет проблем.</p><p>у майка эша есть полное описание в его <a href="http://www.mikeash.com/pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html">уход и кормление синглетонов</a> пост в блоге.</p><p>не все блоки gcd запускаются асинхронно.</p>