Compiler error: "initializer element is not a compile-time constant"
When compiling this code, I get the error "initializer element is not a compile-time constant". Can anyone explain why?
#import "PreferencesController.h"
@implementation PreferencesController
- (id)init
{
self = [super init];
if (self) {
// Ini开发者_StackOverflow中文版tialization code here.
}
return self;
}
NSImage* imageSegment = [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];//error here
When you define a variable outside the scope of a function, that variable's value is actually written into your executable file. This means you can only use a constant value. Since you don't know everything about the runtime environment at compile time (which classes are available, what is their structure, etc.), you cannot create objective c objects until runtime, with the exception of constant strings, which are given a specific structure and guaranteed to stay that way. What you should do is initialize the variable to nil and use +initialize
to create your image. initialize
is a class method which will be called before any other method is called on your class.
Example:
NSImage *imageSegment = nil;
+ (void)initialize {
if(!imageSegment)
imageSegment = [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];
}
- (id)init {
self = [super init];
if (self) {
// Initialization code here.
}
return self;
}
A global variable has to be initialized to a constant value, like 4
or 0.0
or @"constant string"
or nil
. A object constructor, such as init
, does not return a constant value.
If you want to have a global variable, you should initialize it to nil
and then return it using a class method:
NSImage *segment = nil;
+ (NSImage *)imageSegment
{
if (segment == nil) segment = [[NSImage alloc] initWithContentsOfFile:@"/user/asd.jpg"];
return segment;
}
Because you are asking the compiler to initialize a static variable with code that is inherently dynamic.
The reason is that your are defining your imageSegment
outside of a function in your source code (static variable).
In such cases, the initialization cannot include execution of code, like calling a function or allocation a class. Initializer must be a constant whose value is known at compile time.
You can then initialize your static variable inside of your init
method (if you postpone its declaration to init).
You can certainly #define a macro as shown below. The compiler will replace "IMAGE_SEGMENT" with its value before compilation. While you will achieve defining a global lookup for your array, it is not the same as a global variable. When the macro is expanded, it works just like inline code and so a new image is created each time. So if you are careful in where you use the macro, then you would have effectively achieved creating a global variable.
#define IMAGE_SEGMENT [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];
Then use it where you need it as shown below. Each time the below code is executed, a new object is created with a new memory pointer.
imageSegment = IMAGE_SEGMENT
You can use the static singleton approach with dispatch_once
:
#define STATIC_VAR(type, code) ^type() { \
static type object; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
object = code; \
}); \
return object; \
};
#define let __auto_type const
let imageSegment = STATIC_VAR(UIImage*, [[UIImage alloc] initWithContentsOfFile:@"image.jpg"]);
let imageRect = STATIC_VAR(CGRect, CGRectMake(0, 0, 100, 100));
// How to use:
- (void)viewDidLoad {
[super viewDidLoad];
self.imageView.image = imageSegment();
self.imageView.frame = imageRect();
}
It is thread safe, works lazily with any type and makes only a single instance.
I got this error while practicing C language, my code that I was trying to run was this
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char *name;
int age;
} person;
person *p = (person *)malloc(sizeof(person));
and I realized while reading answers, that in C, I should have main function, which I forgot to use, so put the person code in main function, thus removing the error as follows
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char *name;
int age;
} person;
int main()
{
person *p = (person *)malloc(sizeof(person));
return 0;
}
精彩评论