How to wait for initialization to complete before returning a singleton instance in SwiftHow to call Objective-C code from SwiftUsing a dispatch_once singleton model in SwiftSwift Beta performance: sorting arraysHow to call a class method in a convenience initializer in SwiftDoes Swift execute the methods of a class as part of initializing it?Wait until Boolean is True in Swift?In Swift, What is the difference between a Singleton and the static version of a class?How to wait for Function to finish before continuingiOS will CATransaction wait after viewDidDisappear before calling the completion blockThread safety of method calls on “shared” static constant property

Why do we use caret (^) as the symbol for ctrl/control?

Are there any Final Fantasy Spirits in Super Smash Bros Ultimate?

What is the name of this hexagon/pentagon polyhedron?

Manager is threatening to grade me poorly if I don't complete the project

What is the difference between 'unconcealed' and 'revealed'?

How might a mountain bowl form?

Point of the the Dothraki's attack in GoT S8E3?

Is there something "wrong" with my writing? How do I improve it?

Is it possible to know which is the correct temperature range and speed for any model?

What property of a BJT transistor makes it an amplifier?

Reducing the white spacing

Why is "Vayechulu" said 3 times on Leil Shabbat?

Can there be a single technologically advanced nation, in a continent full of non-technologically advanced nations?

SQLServerLogMgr::LogWriter: Operating system error 1117

Is this homebrew life-stealing melee cantrip unbalanced?

How to calculate the node voltages for this circuit using the voltage divider rule

What does a spell range of "25 ft. + 5 ft./2 levels" mean?

How do LIGO and VIRGO know that a gravitational wave has its origin in a neutron star or a black hole?

Timing of New Changes in Change Sets

Have I damaged my car by attempting to reverse with hand/park brake up?

Why Isn’t SQL More Refactorable?

What matters more when it comes to book covers? Is it ‘professional quality’ or relevancy?

Distribution normality check

Did we get closer to another plane than we were supposed to, or was the pilot just protecting our delicate sensibilities?



How to wait for initialization to complete before returning a singleton instance in Swift


How to call Objective-C code from SwiftUsing a dispatch_once singleton model in SwiftSwift Beta performance: sorting arraysHow to call a class method in a convenience initializer in SwiftDoes Swift execute the methods of a class as part of initializing it?Wait until Boolean is True in Swift?In Swift, What is the difference between a Singleton and the static version of a class?How to wait for Function to finish before continuingiOS will CATransaction wait after viewDidDisappear before calling the completion blockThread safety of method calls on “shared” static constant property






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















I have a singleton class, which requires a network operation with asynchronous callback to initialize. Any member function of that class should only be called when initialization callback finished.



What I'm not clear with, is how to wait for asynch callback to finish before I return a singleton instance to a caller? Or maybe is there any other way to ensure initialization completes before any function can be called (only initialization should be sequential, all operations after that shouldn't be).



Here's the minimal code:



class DataProvider 

public static let instance: DataProvider
// on first call wait here until callback is done
// on subsequent calls, no need to wait since already initialized
return internalInstance


private static let internalInstance = DataProvider()

private init()
initialize()


private func initialize()
Something.callAsynch (result, error) in
// instance becomes ready when this line is executed



public func doSomething()
// this function should only run after asynch callback was executed




This class is called by other classes and potentially other threads like this:



DataProvider.instance.doSomething()









share|improve this question






















  • @George_E I am familiar with them in general, just not sure how to use them in this case. If you have a specific idea, please post, even a gist will do

    – Kiril S.
    Mar 22 at 21:59











  • The simplest solution would be to pass a closure as a parameter to doSomething. While your resource is loading you store the closures in an array. When it's done you call all the closures with the resource. After that you can execute any calls to doSomething immediately

    – Augusto Dias Noronha
    Mar 22 at 22:00











  • @KirilS. Must have not fully understood the question, sorry!

    – George_E
    Mar 22 at 22:00











  • A second solution would be to use NSNotificationCenter

    – Augusto Dias Noronha
    Mar 22 at 22:05












  • @AugustoDiasNoronha in both cases it pushes responsibility of synchronization to the callers. I was trying to avoid this, since this class only needs to be asynchronous once (on initialization), later it just holds to that static data. I was planning to do initialization early, minimizing the chances that caller needs to wait. So making callers (and there's up to 5 of them) dance around this asynch init problem is less preferable than solving it here within the class itself

    – Kiril S.
    Mar 22 at 22:16


















0















I have a singleton class, which requires a network operation with asynchronous callback to initialize. Any member function of that class should only be called when initialization callback finished.



What I'm not clear with, is how to wait for asynch callback to finish before I return a singleton instance to a caller? Or maybe is there any other way to ensure initialization completes before any function can be called (only initialization should be sequential, all operations after that shouldn't be).



Here's the minimal code:



class DataProvider 

public static let instance: DataProvider
// on first call wait here until callback is done
// on subsequent calls, no need to wait since already initialized
return internalInstance


private static let internalInstance = DataProvider()

private init()
initialize()


private func initialize()
Something.callAsynch (result, error) in
// instance becomes ready when this line is executed



public func doSomething()
// this function should only run after asynch callback was executed




This class is called by other classes and potentially other threads like this:



DataProvider.instance.doSomething()









share|improve this question






















  • @George_E I am familiar with them in general, just not sure how to use them in this case. If you have a specific idea, please post, even a gist will do

    – Kiril S.
    Mar 22 at 21:59











  • The simplest solution would be to pass a closure as a parameter to doSomething. While your resource is loading you store the closures in an array. When it's done you call all the closures with the resource. After that you can execute any calls to doSomething immediately

    – Augusto Dias Noronha
    Mar 22 at 22:00











  • @KirilS. Must have not fully understood the question, sorry!

    – George_E
    Mar 22 at 22:00











  • A second solution would be to use NSNotificationCenter

    – Augusto Dias Noronha
    Mar 22 at 22:05












  • @AugustoDiasNoronha in both cases it pushes responsibility of synchronization to the callers. I was trying to avoid this, since this class only needs to be asynchronous once (on initialization), later it just holds to that static data. I was planning to do initialization early, minimizing the chances that caller needs to wait. So making callers (and there's up to 5 of them) dance around this asynch init problem is less preferable than solving it here within the class itself

    – Kiril S.
    Mar 22 at 22:16














0












0








0








I have a singleton class, which requires a network operation with asynchronous callback to initialize. Any member function of that class should only be called when initialization callback finished.



What I'm not clear with, is how to wait for asynch callback to finish before I return a singleton instance to a caller? Or maybe is there any other way to ensure initialization completes before any function can be called (only initialization should be sequential, all operations after that shouldn't be).



Here's the minimal code:



class DataProvider 

public static let instance: DataProvider
// on first call wait here until callback is done
// on subsequent calls, no need to wait since already initialized
return internalInstance


private static let internalInstance = DataProvider()

private init()
initialize()


private func initialize()
Something.callAsynch (result, error) in
// instance becomes ready when this line is executed



public func doSomething()
// this function should only run after asynch callback was executed




This class is called by other classes and potentially other threads like this:



DataProvider.instance.doSomething()









share|improve this question














I have a singleton class, which requires a network operation with asynchronous callback to initialize. Any member function of that class should only be called when initialization callback finished.



What I'm not clear with, is how to wait for asynch callback to finish before I return a singleton instance to a caller? Or maybe is there any other way to ensure initialization completes before any function can be called (only initialization should be sequential, all operations after that shouldn't be).



Here's the minimal code:



class DataProvider 

public static let instance: DataProvider
// on first call wait here until callback is done
// on subsequent calls, no need to wait since already initialized
return internalInstance


private static let internalInstance = DataProvider()

private init()
initialize()


private func initialize()
Something.callAsynch (result, error) in
// instance becomes ready when this line is executed



public func doSomething()
// this function should only run after asynch callback was executed




This class is called by other classes and potentially other threads like this:



DataProvider.instance.doSomething()






swift






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 22 at 21:54









Kiril S.Kiril S.

5,81652245




5,81652245












  • @George_E I am familiar with them in general, just not sure how to use them in this case. If you have a specific idea, please post, even a gist will do

    – Kiril S.
    Mar 22 at 21:59











  • The simplest solution would be to pass a closure as a parameter to doSomething. While your resource is loading you store the closures in an array. When it's done you call all the closures with the resource. After that you can execute any calls to doSomething immediately

    – Augusto Dias Noronha
    Mar 22 at 22:00











  • @KirilS. Must have not fully understood the question, sorry!

    – George_E
    Mar 22 at 22:00











  • A second solution would be to use NSNotificationCenter

    – Augusto Dias Noronha
    Mar 22 at 22:05












  • @AugustoDiasNoronha in both cases it pushes responsibility of synchronization to the callers. I was trying to avoid this, since this class only needs to be asynchronous once (on initialization), later it just holds to that static data. I was planning to do initialization early, minimizing the chances that caller needs to wait. So making callers (and there's up to 5 of them) dance around this asynch init problem is less preferable than solving it here within the class itself

    – Kiril S.
    Mar 22 at 22:16


















  • @George_E I am familiar with them in general, just not sure how to use them in this case. If you have a specific idea, please post, even a gist will do

    – Kiril S.
    Mar 22 at 21:59











  • The simplest solution would be to pass a closure as a parameter to doSomething. While your resource is loading you store the closures in an array. When it's done you call all the closures with the resource. After that you can execute any calls to doSomething immediately

    – Augusto Dias Noronha
    Mar 22 at 22:00











  • @KirilS. Must have not fully understood the question, sorry!

    – George_E
    Mar 22 at 22:00











  • A second solution would be to use NSNotificationCenter

    – Augusto Dias Noronha
    Mar 22 at 22:05












  • @AugustoDiasNoronha in both cases it pushes responsibility of synchronization to the callers. I was trying to avoid this, since this class only needs to be asynchronous once (on initialization), later it just holds to that static data. I was planning to do initialization early, minimizing the chances that caller needs to wait. So making callers (and there's up to 5 of them) dance around this asynch init problem is less preferable than solving it here within the class itself

    – Kiril S.
    Mar 22 at 22:16

















@George_E I am familiar with them in general, just not sure how to use them in this case. If you have a specific idea, please post, even a gist will do

– Kiril S.
Mar 22 at 21:59





@George_E I am familiar with them in general, just not sure how to use them in this case. If you have a specific idea, please post, even a gist will do

– Kiril S.
Mar 22 at 21:59













The simplest solution would be to pass a closure as a parameter to doSomething. While your resource is loading you store the closures in an array. When it's done you call all the closures with the resource. After that you can execute any calls to doSomething immediately

– Augusto Dias Noronha
Mar 22 at 22:00





The simplest solution would be to pass a closure as a parameter to doSomething. While your resource is loading you store the closures in an array. When it's done you call all the closures with the resource. After that you can execute any calls to doSomething immediately

– Augusto Dias Noronha
Mar 22 at 22:00













@KirilS. Must have not fully understood the question, sorry!

– George_E
Mar 22 at 22:00





@KirilS. Must have not fully understood the question, sorry!

– George_E
Mar 22 at 22:00













A second solution would be to use NSNotificationCenter

– Augusto Dias Noronha
Mar 22 at 22:05






A second solution would be to use NSNotificationCenter

– Augusto Dias Noronha
Mar 22 at 22:05














@AugustoDiasNoronha in both cases it pushes responsibility of synchronization to the callers. I was trying to avoid this, since this class only needs to be asynchronous once (on initialization), later it just holds to that static data. I was planning to do initialization early, minimizing the chances that caller needs to wait. So making callers (and there's up to 5 of them) dance around this asynch init problem is less preferable than solving it here within the class itself

– Kiril S.
Mar 22 at 22:16






@AugustoDiasNoronha in both cases it pushes responsibility of synchronization to the callers. I was trying to avoid this, since this class only needs to be asynchronous once (on initialization), later it just holds to that static data. I was planning to do initialization early, minimizing the chances that caller needs to wait. So making callers (and there's up to 5 of them) dance around this asynch init problem is less preferable than solving it here within the class itself

– Kiril S.
Mar 22 at 22:16













1 Answer
1






active

oldest

votes


















3














With some help, I found a good solution, that is both reliable and simple. The solution is to use count-down latch. Unfortunately there's no built-in class like that in Swift, but some implementations could be found online (for example: this class from Uber). So this is a solution:



class DataProvider 

public static let instance: DataProvider
// on first call wait here until callback is done
// on subsequent calls, no need to wait since already initialized
return internalInstance

private static let internalInstance = DataProvider()

private let initLatch = CountDownLatch(1)

private init()
initialize()


private func initialize()
Something.callAsynch (result, error) in
// instance becomes ready when this line is executed
initLatch.countDown()



public func doSomething()
initLatch.await()
// this function should only run after asynch callback was executed




So what does it do:



  • the latch is set to 1 so any caller of doSomething will be suspended until latch is decremented to 0

  • latch is only decremented to 0 in one place (init completion callback), hence nobody will proceed before initialization completed

  • but after latch is set to 0, calling doSomething will not be delayed

Notes:



  • This is a simplified model for problem and solution. In reality there are some other factors that may need to be taken into account, and would require other concurrency tools.

  • In my case, the callers are non-interactive, hence I do want them to wait rather than be asynchronous. If callers were interactive, I'd let them deal with asynchronous nature of this class instead.





share|improve this answer

























  • Thanks for tagging me, this is a pretty elegant solution!

    – Augusto Dias Noronha
    Mar 24 at 23:00











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55308276%2fhow-to-wait-for-initialization-to-complete-before-returning-a-singleton-instance%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














With some help, I found a good solution, that is both reliable and simple. The solution is to use count-down latch. Unfortunately there's no built-in class like that in Swift, but some implementations could be found online (for example: this class from Uber). So this is a solution:



class DataProvider 

public static let instance: DataProvider
// on first call wait here until callback is done
// on subsequent calls, no need to wait since already initialized
return internalInstance

private static let internalInstance = DataProvider()

private let initLatch = CountDownLatch(1)

private init()
initialize()


private func initialize()
Something.callAsynch (result, error) in
// instance becomes ready when this line is executed
initLatch.countDown()



public func doSomething()
initLatch.await()
// this function should only run after asynch callback was executed




So what does it do:



  • the latch is set to 1 so any caller of doSomething will be suspended until latch is decremented to 0

  • latch is only decremented to 0 in one place (init completion callback), hence nobody will proceed before initialization completed

  • but after latch is set to 0, calling doSomething will not be delayed

Notes:



  • This is a simplified model for problem and solution. In reality there are some other factors that may need to be taken into account, and would require other concurrency tools.

  • In my case, the callers are non-interactive, hence I do want them to wait rather than be asynchronous. If callers were interactive, I'd let them deal with asynchronous nature of this class instead.





share|improve this answer

























  • Thanks for tagging me, this is a pretty elegant solution!

    – Augusto Dias Noronha
    Mar 24 at 23:00















3














With some help, I found a good solution, that is both reliable and simple. The solution is to use count-down latch. Unfortunately there's no built-in class like that in Swift, but some implementations could be found online (for example: this class from Uber). So this is a solution:



class DataProvider 

public static let instance: DataProvider
// on first call wait here until callback is done
// on subsequent calls, no need to wait since already initialized
return internalInstance

private static let internalInstance = DataProvider()

private let initLatch = CountDownLatch(1)

private init()
initialize()


private func initialize()
Something.callAsynch (result, error) in
// instance becomes ready when this line is executed
initLatch.countDown()



public func doSomething()
initLatch.await()
// this function should only run after asynch callback was executed




So what does it do:



  • the latch is set to 1 so any caller of doSomething will be suspended until latch is decremented to 0

  • latch is only decremented to 0 in one place (init completion callback), hence nobody will proceed before initialization completed

  • but after latch is set to 0, calling doSomething will not be delayed

Notes:



  • This is a simplified model for problem and solution. In reality there are some other factors that may need to be taken into account, and would require other concurrency tools.

  • In my case, the callers are non-interactive, hence I do want them to wait rather than be asynchronous. If callers were interactive, I'd let them deal with asynchronous nature of this class instead.





share|improve this answer

























  • Thanks for tagging me, this is a pretty elegant solution!

    – Augusto Dias Noronha
    Mar 24 at 23:00













3












3








3







With some help, I found a good solution, that is both reliable and simple. The solution is to use count-down latch. Unfortunately there's no built-in class like that in Swift, but some implementations could be found online (for example: this class from Uber). So this is a solution:



class DataProvider 

public static let instance: DataProvider
// on first call wait here until callback is done
// on subsequent calls, no need to wait since already initialized
return internalInstance

private static let internalInstance = DataProvider()

private let initLatch = CountDownLatch(1)

private init()
initialize()


private func initialize()
Something.callAsynch (result, error) in
// instance becomes ready when this line is executed
initLatch.countDown()



public func doSomething()
initLatch.await()
// this function should only run after asynch callback was executed




So what does it do:



  • the latch is set to 1 so any caller of doSomething will be suspended until latch is decremented to 0

  • latch is only decremented to 0 in one place (init completion callback), hence nobody will proceed before initialization completed

  • but after latch is set to 0, calling doSomething will not be delayed

Notes:



  • This is a simplified model for problem and solution. In reality there are some other factors that may need to be taken into account, and would require other concurrency tools.

  • In my case, the callers are non-interactive, hence I do want them to wait rather than be asynchronous. If callers were interactive, I'd let them deal with asynchronous nature of this class instead.





share|improve this answer















With some help, I found a good solution, that is both reliable and simple. The solution is to use count-down latch. Unfortunately there's no built-in class like that in Swift, but some implementations could be found online (for example: this class from Uber). So this is a solution:



class DataProvider 

public static let instance: DataProvider
// on first call wait here until callback is done
// on subsequent calls, no need to wait since already initialized
return internalInstance

private static let internalInstance = DataProvider()

private let initLatch = CountDownLatch(1)

private init()
initialize()


private func initialize()
Something.callAsynch (result, error) in
// instance becomes ready when this line is executed
initLatch.countDown()



public func doSomething()
initLatch.await()
// this function should only run after asynch callback was executed




So what does it do:



  • the latch is set to 1 so any caller of doSomething will be suspended until latch is decremented to 0

  • latch is only decremented to 0 in one place (init completion callback), hence nobody will proceed before initialization completed

  • but after latch is set to 0, calling doSomething will not be delayed

Notes:



  • This is a simplified model for problem and solution. In reality there are some other factors that may need to be taken into account, and would require other concurrency tools.

  • In my case, the callers are non-interactive, hence I do want them to wait rather than be asynchronous. If callers were interactive, I'd let them deal with asynchronous nature of this class instead.






share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 24 at 19:14

























answered Mar 24 at 17:52









Kiril S.Kiril S.

5,81652245




5,81652245












  • Thanks for tagging me, this is a pretty elegant solution!

    – Augusto Dias Noronha
    Mar 24 at 23:00

















  • Thanks for tagging me, this is a pretty elegant solution!

    – Augusto Dias Noronha
    Mar 24 at 23:00
















Thanks for tagging me, this is a pretty elegant solution!

– Augusto Dias Noronha
Mar 24 at 23:00





Thanks for tagging me, this is a pretty elegant solution!

– Augusto Dias Noronha
Mar 24 at 23:00



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55308276%2fhow-to-wait-for-initialization-to-complete-before-returning-a-singleton-instance%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해