编译此代码时,我得到错误"初始化元素不是编译时常量".有谁能解释为什么?
#import "PreferencesController.h"
@implementation PreferencesController
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
}
return self;
}
NSImage* imageSegment = [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];//error here
Run Code Online (Sandbox Code Playgroud) cocoa compiler-errors initialization global-variables objective-c
我有一个名为Constants.h的文件:
extern NSString * const BASE_URL;
Run Code Online (Sandbox Code Playgroud)
和Constants.m:
#ifdef DEBUG
NSString * const BASE_URL = @"http://www.example.org ";
#else
NSString * const BASE_URL = @"http://localhost";
#endif
Run Code Online (Sandbox Code Playgroud)
第一个问题:我如何切换DEBUG是True
和False
?
我有一个视图控制器文件MyViewController.m
:
#import "MyViewController.h"
#import "Constants.h"
// this doesn't works. see above for the error.
static NSString * const ANOTHER_URL = [NSString stringWithFormat:@"%@%@", BASE_URL, @"/path/"];
@implementation HomeViewController
[...]
Run Code Online (Sandbox Code Playgroud)
代码不起作用并返回此错误:
error: Semantic Issue: Initializer element is not a compile-time constant
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?
我需要将几个全局字符串变量与其他字符串组合以创建各种URL.
更新1
现在Constants.m
是:
#import …
Run Code Online (Sandbox Code Playgroud) 使用它有什么好处:
+ (CardPainter*) sharedPainter {
static CardPainter* sp = nil;
if (nil == sp) {
sp = [[CardPainter alloc] init];
}
return sp;
}
Run Code Online (Sandbox Code Playgroud)
而不是这个:
+ (CardPainter*) sharedPainter {
static CardPainter* sp = [[CardPainter alloc] init];
return sp;
}
Run Code Online (Sandbox Code Playgroud)
静态变量初始化只执行一次,所以我看不到前者的优点.
注意:我使用的是Objective-C ++,其中允许使用非编译时常量(/sf/answers/861337081/)
+ (Foo)sharedFoo
{
static Foo *foo = [Foo new];
return foo;
}
Run Code Online (Sandbox Code Playgroud)
静态初始化程序只能运行一次,但是它是否具有线程安全性,例如,如果多个线程同时调用+(Foo)sharedFoo,是否可以保证[Foo new]仅运行一次?
我问是因为如果这样,那么为什么建议obj-C中的单例模式使用如下所示的dispatch_once呢?
+ (Foo)sharedFoo {
static Foo *foo = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
foo = [Foo new];
});
return foo;
}
Run Code Online (Sandbox Code Playgroud)
我本质上是在问为什么第一行不能只是
static Foo *foo = [Foo new];
Run Code Online (Sandbox Code Playgroud)
如果我们知道静态本地var初始化仅运行一次,则只需完全跳过dispatch_once。
编辑:好的,我找到了答案。1.首先,我意识到我使用的是Objective-C ++,它允许上述代码进行编译(并在运行时运行)2.第二,编译器将该代码转换为不带dispatch_once的单例初始化器的“原始”版本,从而使它确实不是线程安全的。