gpt4 book ai didi

iphone - + (void) 未调用初始化( Objective-C )

转载 作者:太空狗 更新时间:2023-10-30 03:25:40 26 4
gpt4 key购买 nike

我的方法 + (void) initialized 没有被调用,我是 Objective C 的新手。代码在 iPhone Game Development 一书中,我必须显式调用该方法才能工作。 .m 文件中的代码是:

ResourceManager *g_ResManager;

@implementation ResourceManager

//initialize is called automatically before the class gets any other message, per from http://stackoverflow.com/questions/145154/what-does-your-objective-c-singleton-look-like
+ (void) initialize
{
static BOOL initialized = NO;
if(!initialized)
{
initialized = YES;
g_ResManager = [[ResourceManager alloc] init];
}
}

...

@end

但是在 .h 文件中进行了变量的外部声明:

extern ResourceManager *g_ResManager; //paul <3's camel caps, hungarian notation, and underscores.

@interface ResourceManager : NSObject {
...
}
...
@end

我尝试了所有方法(删除外部,将 static 放在 .m 声明中)并且总是出现编译错误。上面的代码可以编译,但方法 initialize 从未被调用(设置断点以查看)。

一些线索?

最佳答案

+initialize 在您向该类的实例发送一些消息之前不会被调用。你发信息了吗?

一个可能的问题是您从代码的另一部分向 g_ResManager 发送了一条消息?那行不通,因为:

  1. g_ResManager 在启动时为零。
  2. 您向 g_ResManager 发送消息,该消息为 nil
  3. Objective-C 运行时算作“向类发送消息”的不是它在源代码中的句法,而是真正的对象和发送的消息。
  4. 因此,在这种情况下,nil 得到消息,nil 不是 ResourceManager 的实例,所以 +initialize 也没有被调用。

我会按如下方式更改您的代码:首先,在 .m 中,

static ResourceManager *g_ResManager;

@implementation ResourceManager

//initialize is called automatically before the class gets any other message
+ (void) initialize
{
static BOOL initialized = NO;
if(!initialized)
{
initialized = YES;
g_ResManager = [[ResourceManager alloc] init];
}
}
+(ResourceManager*)sharedResourceManager
{
return g_ResManager;
}
...

@end

然后在 .h 中,我只需要

@interface ResourceManager:NSObject {
...
}
+(ResourceManager*)sharedResourceManager
@end

然后,您可以随时使用 [ResourceManager sharedResourceManager]

事实上,正如 Rob 在评论中所说,在这种情况下你完全可以不用 +initialize 。将 .m 更改为类似

@implementation ResourceManager

+(ResourceManager*)sharedResourceManager
{
static ResourceManager *g_ResManager=nil;
if(!g_ResManager){
g_ResManager=[[ResourceManager alloc] init];
}
return g_ResManager;
}
...

@end

这是我个人经常使用的成语。但是我警告你这不是完全线程安全的!只要在生成线程之前调用一次 [ResourceManager sharedResourceManager] 就应该没问题,我几乎总是这样做,但这是要记住的一件事。另一方面,由于 +initialize 定义明确的行为,上面使用 +initialize 的版本应该是线程安全的。请参阅 this blog post 中的讨论.

关于iphone - + (void) 未调用初始化( Objective-C ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2178429/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com