Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective-C中的单态混淆_Objective C - Fatal编程技术网

Objective-C中的单态混淆

Objective-C中的单态混淆,objective-c,Objective C,考虑以下代码: +(id)sharedInstance { static dispatch_once_t pred; static MyClass *sharedInstance = nil; dispatch_once(&pred, ^{ sharedInstance = [[MyClass alloc] init]; }); return sharedInstance; } + (MotionManagerSingleton*

考虑以下代码:

+(id)sharedInstance
{
    static dispatch_once_t pred;
    static MyClass *sharedInstance = nil;
    dispatch_once(&pred, ^{
        sharedInstance = [[MyClass alloc] init];
    });
    return sharedInstance;
}
+ (MotionManagerSingleton*)sharedInstance {

    static MotionManagerSingleton *_sharedInstance;
    if(!_sharedInstance) {
        static dispatch_once_t oncePredicate;
        dispatch_once(&oncePredicate, ^{
            _sharedInstance = [[super allocWithZone:nil] init];
            });
    }

    return _sharedInstance;
}

+ (id)allocWithZone:(NSZone *)zone {    

    return [self sharedInstance];
}

- (id)copyWithZone:(NSZone *)zone {
    return self;    
}
如果我遵循这种单例设计模式,我可以做出以下假设:

  • 分配和初始化只执行一次 到GCD
  • sharedInstance类变量只能从中访问 在该实现中,并在类之间共享,而不考虑实例
第一次创建实例时,我会执行以下操作:

MyClass *something = [MyClass sharedInstance];
我的问题是,如果我再次调用预览代码,但像这样:

MyClass *somethingOther = [MyClass sharedInstance];
我只能想到一个结果

结果:

static MyClass *sharedInstance = nil;
使sharedInstance类变量指向nil,并返回一个nil,因此其他变量将为nil

但我认为在单例中应该发生的是,将返回共享实例

现在考虑这个代码:

+(id)sharedInstance
{
    static dispatch_once_t pred;
    static MyClass *sharedInstance = nil;
    dispatch_once(&pred, ^{
        sharedInstance = [[MyClass alloc] init];
    });
    return sharedInstance;
}
+ (MotionManagerSingleton*)sharedInstance {

    static MotionManagerSingleton *_sharedInstance;
    if(!_sharedInstance) {
        static dispatch_once_t oncePredicate;
        dispatch_once(&oncePredicate, ^{
            _sharedInstance = [[super allocWithZone:nil] init];
            });
    }

    return _sharedInstance;
}

+ (id)allocWithZone:(NSZone *)zone {    

    return [self sharedInstance];
}

- (id)copyWithZone:(NSZone *)zone {
    return self;    
}
这是

static MotionManagerSingleton *_sharedInstance;
没有将我的变量设置为nil,但我认为默认情况下所有对象指针都初始化为nil

我的问题是,这些类方法如何返回“sharedInstance”


谢谢。未初始化的指针是未初始化的

static MotionManagerSingleton *_sharedInstance;
不会使您的MotionManagerSingleton指向
nil
。它将指向一个未定义的(垃圾)位置


两个。声明的变量
static
只初始化一次(是的,语法与语义有点不一致),因此您的第一个实现不会使返回的共享实例无效。这是一个非常好的实现。

一个。未初始化的指针是未初始化的

static MotionManagerSingleton *_sharedInstance;
不会使您的MotionManagerSingleton指向
nil
。它将指向一个未定义的(垃圾)位置


两个。声明的变量
static
只初始化一次(是的,语法与语义有点不一致),因此您的第一个实现不会使返回的共享实例无效。这是一个非常好的实现。

所以这个静态MyClass*sharedInstance=nil;第二次执行会被忽略吗?因此,将返回以前初始化的变量?静态变量是零初始化的,使用ARC时,所有对象指针都是零初始化的。@JoshuaWeinberg ooo我不知道,静态变量对我来说太混乱了。@LuisOscar,“静态”一词指的是变量的生存期。它的存储是静态的——它不像堆栈上的东西那样是瞬态的,也不像堆上的东西那样是动态的。它是永久的。只有在初始化存储时才会发生初始化。由于存储是永久性的,初始化只发生一次。(实际上,初始化是在编译时进行的。编译器将存储器及其初始值烘焙到可执行文件中,并在加载程序时加载到内存中。)@Kenthomass小心地说静态是在编译时完成的。对于C和Obj-C,这可能是正确的,但对于C++或其他一些语言来说,这可能是正确的。
static
关键字过载,在不同的平台上有许多不同的含义;第二次执行会被忽略吗?因此,将返回以前初始化的变量?静态变量是零初始化的,使用ARC时,所有对象指针都是零初始化的。@JoshuaWeinberg ooo我不知道,静态变量对我来说太混乱了。@LuisOscar,“静态”一词指的是变量的生存期。它的存储是静态的——它不像堆栈上的东西那样是瞬态的,也不像堆上的东西那样是动态的。它是永久的。只有在初始化存储时才会发生初始化。由于存储是永久性的,初始化只发生一次。(实际上,初始化是在编译时进行的。编译器将存储器及其初始值烘焙到可执行文件中,并在加载程序时加载到内存中。)@Kenthomass小心地说静态是在编译时完成的。对于C和Obj-C,这可能是正确的,但对于C++或其他一些语言来说,这可能是正确的。
static
关键字的负载过重,在不同的平台上有许多不同的含义。