Is NetworkManager Singleton Class working properly in Apple Sample MVCNetworking?

Here is a link to sample code http://developer.apple.com/library/ios/#samplecode/MVCNetworking/Introduction/Intro.html

Below is a snippet of code from the NetworkManager.m file

+ (NetworkManager *)sharedManager
// See comment in header.
{
    static NetworkManager * sNetworkManager;

    // This can be called on any thread, so we synchronise.  We only do this in 
    // the sNetworkManager case because, once sNetworkManager goes non-nil, it can 
    // never go nil again.

    if (sNetworkManager == nil) {
        @synchronized (self) {
            sNetworkManager = [[NetworkManager alloc] init];
            assert(sNetworkManager != nil);
        }
    }
    return sNetworkManager;
}

Obviously there are problems with the flow. Two instances of NetworkManager can be created with multiple threads. So Apple made a mistake, right?

+5
source share
3 answers

Yes, that’s wrong. Start with sNetworkManagerboth niland consider two threads T1 and T2.

One possible, if unlikely, scenario:

T1: Determines (sNetworkManager == nil) is true
T2: Determines (sNetworkManager == nil) is true
T1: Takes the @synchronized lock
    Creates a NetworkManager 
    Sets sNetworkManager
    Releases the lock
T2: Takes the @synchronized lock
    Creates a NetworkManager 
    Sets sNetworkManager, LEAKING the first one
    Releases the lock

This question contains safer ways to do it.

+1
source

, . concurrency. alloc:

+ (NetworkManager *)sharedManager
{
    static NetworkManager * sNetworkManager;
    if (sNetworkManager == nil) {
        @synchronized (self) {
            if (sNetworkManager == nil) {
                sNetworkManager = [[NetworkManager alloc] init];
                assert(sNetworkManager != nil);
            }
        }
    }
    return sNetworkManager;
}

Ojbective-C, : Objective-C?

BobCromwell . double check lock , apple Threading Programming Guide:

- . , , . `

+2

There is no error in this code. Only one sNetworkManager is created for the simple reason that the word "static" is used. The static keyword is used here to define a variable as global, but only visible to this function. The variable is allocated on the first call of + (NetworkManager *) sharedManager, then it is no longer zero and is not initialized.

0
source

All Articles