Initializer element is not a compile time constant - objective-c

Using objective-c to write a program. I'm getting an error (initializer element is not a compile-time constant) and am not sure I follow why it's occurring. I'm just trying to initialize an array. I'm also using xcode6. My questions are: how can I rewrite this correctly in Objective-c and what would it look like in the new Swift? Also why is there an error - I don't follow how to implement some of the other threads on this question?
Name.h
#import <Foundation/Foundation.h>
#interface Name : NSObject
#property (nonatomic, retain) NSMutableArray *myArray;
#end
Name.m
#import "Name.h"
#implementation Name
NSMutableArray *myArray = [[NSMutableArray alloc] init]; //error shows up here - initializer element is not a compile-time constant
[myArray addObject:#"Object 1"];
[myArray addObject:#"Object 2"];
[myArray addObject:#"Object 3"];
#end

You should init the variable only inside a method
try override
-(id) init
{
self = [super init];
if(self)
{
myArray = [[NSMutableArray alloc] init];
}
return self;
}

Error
As the error say, you can only initialize compile time constant in the implementation of your class
This will work:
NSString* abcd = #"test";
Because #"test" is a constant and will never change after the compilation of your code.
[[NSMutableArray alloc] init] is not a constant and this is why you got an error. You will have to implement an init method to initialize your array.
Swift
For the swift part of your question:
You can still use NSArray in swift or use the swift Array type.
You can check out the Working with Cocoa Data Types Documentation or the Apple collections types Swift Documentation.
If you still want to use NSArray in swift :
var array:NSMutableArray = NSMutableArray()
array.addObject("test1")
array.addObject("test2")
// or
array:NSMutableArray = ["test1", "test2"]
Or if you want to use the swift array :
var array:String[] = ["test1", "test2"]
// or
var array:String[] = String[]()
array.append("test1")
array.append("test2")

Try to edit you "Building Settings"->"Compile Sources As" to "Objective-C++", maybe can solve your problem.

Related

My own #{} literals

As you know Apple has provided # literals for such classes as NSNumber, NSDictionary, NSArray, so we can create an object this way, for example
NSArray *array = #[obj1, obj2];
So I wonder, if there is a way to create such literals for my own classes? For example, I want to write smth. like
MyClass *object = MyClass[value1, value2];
And I don't want to write long parsers :)
# syntax are literals, which is feature of Clang compiler. Since its compiler feature, NO, you cannot define you own literals.
For more informations about compilers literals, please refer Clang 3.4 documentation - Objective-C Literals
Edit: Also, I just found this interesting SO discussion
Edit: As BooRanger mentioned at the comments, there exists method to create [] accessors (the Collection Literals way) to access custom objects. Its called Object Subscripting. Using this, you can access anything in your custom class like this myObject[#"someKey"]. Read more at NSHipster.
Here is my example implementation of "Subcriptable" object. For example simplicity, it just accesses internal dictionary. Header:
#interface LKSubscriptableObject : NSObject
// Object subscripting
- (id)objectForKeyedSubscript:(id <NSCopying>)key;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;
#end
Implementation:
#implementation LKSubscriptableObject {
NSMutableDictionary *_dictionary;
}
- (id)init
{
self = [super init];
if (self) {
_dictionary = [NSMutableDictionary dictionary];
}
return self;
}
- (id)objectForKeyedSubscript:(id <NSCopying>)key
{
return _dictionary[key];
}
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key
{
_dictionary[key] = obj;
}
#end
You can then access to anything in this object simply using square brackets:
LKSubscriptableObject *subsObj = [[LKSubscriptableObject alloc] init];
subsObj[#"string"] = #"Value 1";
subsObj[#"number"] = #2;
subsObj[#"array"] = #[#"Arr1", #"Arr2", #"Arr3"];
NSLog(#"String: %#", subsObj[#"string"]);
NSLog(#"Number: %#", subsObj[#"number"]);
NSLog(#"Array: %#", subsObj[#"array"]);
Are you okay with this syntax?
MyClass *object = MyClass(value1, value2);
Just define macro like this:
#define MyClass(objects...) [[MyClass alloc] initWithObjects: #[objects]];
Compiler will allow class named MyClass and MyClass() macro.

Why is my NSMutableArray, located in a singleton, returning (null)?

I am working in Xcode 4.5.1 in Objective-C. I’m making a hearing test and want to store relevant data to each question in an array. I made a singleton MyManager. I use this to store data.
It is working fine for simple int/float values etc., but I’m stuck trying to use NSMutableArray. I’m new to Objective-C, so I’m assuming/hoping I've made some obvious mistake.
So, I want to fill mySNRArray with float values. I’ve come to understand that I can’t simply add floats, because it will only take objects. Thus, I use NSNumber.
Problem: When I try to read the data that I’ve supposedly added to the NSMutableArray, I get (null).
I will now provide the relevant code:
MyManager.h
#interface MyManager : NSObject
{
NSMutableArray *mySNRArray;
}
#property (readwrite) NSMutableArray *mySNRArray;
+ (id)sharedManager;
#end
MyManager.m
#implementation MyManager
#synthesize mySNRArray;
+ (id)sharedManager
{
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init
{
if (self = [super init])
{
NSMutableArray *mySNRArray = [[NSMutableArray alloc]init];
}
return self;
}
#end
TestViewController.m
//First, I try to add a value to mySNRArray.
MyManager *Manager = [MyManager sharedManager];
NSNumber *tempStorage1 = [[NSNumber alloc] initWithFloat:mySNR];
[Manager.mySNRArray insertObject:tempStorage1 atIndex:questionNumber];
//The NSLog below is showing the correct value.
NSLog(#"%# : mySNR", tempStorage1);
...
for (n = 0; n < questionNumber; n++)
{
//Second, I try to acces the values I supposedly added to mySNRArray.
MyManager *Manager = [MyManager sharedManager];
//This NSLog below is showing (null).
NSLog(#"Value at %i in SNRArray = %#", n, [Manager.mySNRArray objectAtIndex:n]);
}
...
I hope somebody can explain my error.
change
NSMutableArray *mySNRArray = [[NSMutableArray alloc]init];
to
self->_mySNRArray = [[NSMutableArray alloc]init];
in your init method you are creating a local mutable array, but not assigning it to your property
Instead of creating a new object, use the ivar you created..in the init method.
_mySNRArray = [[NSMutableArray alloc]init];
Even you can ommit these, from your .h
{
NSMutableArray *mySNRArray;
}
+ (id)sharedManager
returns a value
static MyManager* sharedManager
Change the interface to
+ (MyManager*)sharedManager
and the compiler will tell you exactly what mistake you made.

Array Count is 0 after adding an element?

I'm using the code below to add an Object of my Platform class (basic storage class, subclass of NSObject) to an NSMutableArray.
But the NSLog statement outputs 0.
How can this happen?
Platform *platform = [Platform platformWithLabel:label identifier:identfier];
[self.platforms addObject:platform];
NSLog(#"%i", [self.platforms count]);
This is the creation method of Platform:
+(Platform *)platformWithLabel:(NSString *)label identifier:(int)identifier
{
Platform *platform = [[Platform alloc] init];
platform.label = label;
platform.identifier = identifier;
return platform;
}
I'm using ARC. This is how I declare my platforms array:
#property (strong, nonatomic) NSMutableArray *platforms;
Probably you are forgetting to initialize the NSMutableArray itself. Check and make sure you're doing so.
Most likely you're not initializing your self.platforms array.
Don't forget to initializing the NSMutableArray :)
platforms = [[NSMutableArray alloc] init];

iOS - NSMutableArray shows objects out of bounds on setting property

I have implemented the following code to assign NSMutableArray to a property -
NSMutableArray * anArray = [responseDictionary valueForKeyPath:#"tags"];
NSLog(#"The array length is=%d",[anArray count]);
for (NSString *s in anArray) {
NSLog(#"you are %#", s);
}
[self setActiveTagArray:anArray];
It prints out the string values fine. But in the setter function, if I place a breakpoint I see that it shows there are two objects but they are "Out of Scope". What does this mean? What am I doing wrong? My getter also does not fetch any values. The property functions -
-(void)setActiveTagArray:(NSMutableArray *)tags
{
activeTagArray = [[NSMutableArray alloc] init];
activeTagArray = tags;
//NSLog(#"%#",[activeTagArray count]);
}
-(NSMutableArray *)getActiveTagArray
{
return activeTagArray;
}
Is activeTagArray a class variable as well as a property. Consider using _activeTagArray as the class variable name. And then in the .m file just use #synthesize activeTagArray = _activeTagArray;, and for get the second two methods completely.
Response to comment:
You said "I have implemented the following code to assign NSMutableArray to a property". I took this to mean you have "#property (nonatomic, retain) NSMutableArray *activeTagArray;" in your .h file. If this is the case then you would access it thru otherObject'sNameForYourClassHere.activeTagArray.
#synthesize create accessors & mutators for you.

Having trouble adding objects to NSMutableArray in Objective C

I am using the iPhone SDK and have an issue doing something simple. I am trying to add an NSNumber object to an NSMutableArray instance variable. I tried adding NSNumber card to NSMutableArray viewedCardsArray, however without breaking, it does not get added to the array. Here is the code.
/////////////////////////////////////////////////////
// Inside the header file Class.h
#interface MyViewController : UIViewController {
NSMutableArray *viewedCardsArray;
//snip ...
}
#property (nonatomic, retain) NSMutableArray *viewedCardsArray;
#end
/////////////////////////////////////////////////////
// Inside the methods file Class.m
#import "StudyViewController.h"
#implementation StudyViewController
#synthesize viewedCardsArray
//snip ...
- (IBAction)doShowCard {
//snip ...
NSNumber *cardIdObject = [[NSNumber alloc] initWithInt:(int)[self.currentCard cardId]];
[viewedCardsArray addObject: cardIdObject];
[cardIdObject release];
}
So this code executes, and does not seem to leak (according to the Leaks performance tool). However when stepping through the code, at no point does CardIdObject appear in viewedCardsArray.
Looking through SO, I know these basic questions are pretty common to ObjC newbies (like me) so apologies in advance!
Have you initialized your viewedCardsArray? If not you need to somewhere - this is usually done in the init method for your class:
- (id)init
{
self = [super init];
if(self) {
viewedCardsArray = [[NSMutableArray alloc] init];
}
return self;
}
Then it is released in the dealloc method:
- (void)dealloc
{
[viewedCardsArray release];
[super dealloc];
}
Perspx has outlined one way of initializing the array. However, you can also use the class methods provided by NSArray:
self. viewedCardsArray = [NSMutableArray array];
This can go in init or elsewhere.
Note: The object will be autoreleased.