NEAppProxyProvider: instances, properties and statics

Has anyone else seen a problem with how an AppProxy provider extension is allocated and loaded?

I observed that each time startProxyWithOptions method is called that a new instance of NEAppProxyProvider subclass is created. The AppProxy is stopped by calling [self cancelProxyWithError:nil]. However, any static variables retain their values the next time that the AppProxy is started.


It is not a huge deal, but I wonder if this is the intended behavior. Singletons in particular will break if you are using the common pattern:


+ (id)sharedManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken_, ^{
        instance_ = [[self alloc] init];
    });
    return instance_;
}


I did not try Swift to see if it is similar behavior.

Accepted Answer

However, any static variables retain their values the next time that the AppProxy is started.

That’s not a huge surprise. Starting a process is (relatively) expensive, so it’s reasonable for the Network Extension infrastructure to reuse an existing extension process if an appropriate one is lying around. And if your NEProvider instance is created in the same process as some previous one, it’ll share its static variables.

This behaviour is common to all extensions, network and otherwise, because it’s inherited from the underlying XPC Service infrastructure.

Singletons in particular will break if you are using the common pattern:

I don’t consider that to be ‘broken’. The definition of a singleton is that there’s only one instance per process, and that’s what’s happening here. If you don’t want that, don’t use a singleton.

Regardless of the above, you should consider avoiding singletons for other reasons (most importantly, to enhance testability).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks Quinn,

Yeah, you are right and it wasn't a huge surprise for me either. But my initial design was more applicable for a main app, but NEProviders should be designed as a library.


> Regardless of the above, you should consider avoiding singletons for other reasons (most importantly, to enhance testability).

Totally agree. And I'm usually the one telling everyone that singletons are the root of all evils :)

Anyway, I only have one singleton and it is trivial to factor out.


Thanks again for your help,

Andy

NEAppProxyProvider: instances, properties and statics
 
 
Q