Array Allocation in Objective C++ - iphone

I want to declare an array of numbers that is flexible in size in an obj C file
I am doing this:
long * arr = NULL;
a[0] = 0;
but this is giving bad_excess error
Can anyone help me out
also
long *arr = malloc(sizeof(long));
doesn't seem to help either

Why don't you do something like this,
NSMutableArray *numArray = [[NSMutableArray alloc] init];
This creates a array of objects. You can add any number of objects to it. Here you want to add long values. So use the following code,
[numArray addObject:[NSNumber numberWithLong:37];
[numArray addObject:[NSNumber numberWithLong:45];
[numArray addObject:[NSNumber numberWithLong:12];
NSMutableArray is flexible in size as you expected. You can add any number of objects.
If you want to get the number, you can do like the following,
long num1 = [[numArray objectAtIndex:0] longValue];
long num2 = [[numArray objectAtIndex:1] longValue];
You can also do as specified in the following link,
How to declare an array of floats as a class variable in Objective-C when the dimension is undefined at the class instantiation time?

Related

Storing a double array as NSNumber

I have a variable double * data = malloc(sizeof(double)) in objectiveC;
I am using this variable as an double array like data[] to store some data. Now I want to add this data variable (which is an double* array) as an object NSNumber in iOS. Any idea how I can turn it into iOS object likeNSNumber`?
You can use NSData to wrap an arbitrary byte buffer into an Objective-C object.
Use dataWithBytes:length: to create an NSData object from your double array, and bytes: or getBytes:length: to retrieve the data bytes back from the NSData object.
You cannot turn an array of primitives into one NSNumber. This does not make any sense.
You can, however, turn an array of doubles into an array of NSNumbers. Iterate through your double* array and add each number to an NSMutableArray as NSNumber using its class method numberWithDouble:.
Based on Mundi's answer, try this:
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];
for (int i = 0; i < lengthOfDoublearray; i++) { // as premitive DataType array needs predefined length
[array addObject:[NSNumber numberWithDouble:data[i]]];
}
Here data is array of double (that you used).

What are the basic differences between these ways creating and handling arrays?

I am unsure which way to declare my arrays with fixed size of 10 objects of type MyClass and what are the implications of these different alternatives for efficiency, ease of coding or anything else.
...keeping in mind the new xCode4.4 features, esp:
For the NSArray and NSDictionary classes, support is provided for
Objective-C literals.
Subscripting using '[ ]' syntax is supported for Objective-C
container objects.
...and of course using ARC
In particular I need to write contructor methods that return these arrays as a result.
Alternative1
MyClass* objectOfMyClass;
MyClass* array1[10];
array1[5] = objectOfMyClass;
Declaration of method:
- (MyClass*[]) createArray { <--- is this declaration correct like this ?
ps. AFAIK these arrays are put on the stack memory - but I am not sure!
Alternative2
MyClass* objectOfMyClass;
NSMutableArray *array2 = [[NSMutableArray alloc] init];
for (int i = 0; i<10; i++)
[array2 addObject:objectOfMyClass]; //objects get added in some way...
//can't directly access nTh object in this case, need to add from 0 to 9
//conversion to non mutable array, since size will not change anymore
NSArray *array3 = [NSArray arrayWithArray:array2];
Declaration of method:
- (NSArray*) createArray {
ps. AFAIK these arrays are put in main memory - not stack - but I am not sure!
Alternative3
NSArray *array4 = [[NSArray alloc] init];
array4 = ...how to prepare the array so it can hold 10 objects without using NSMutableArray ?
otherwise I do not see a difference to alternative 2...
for (int i = 0; i<10; i++)
array4[i] = objectOfMyClass];
Declaration of method:
- (NSArray*) createArray {
Many thanks for bringing light into this!
There is a great article about literals here. You cannot do Alternative 1. The best way to do this is:
NSMutableArray *holdsMyClass = [NSMutableArray arrayWithCapacity:10]; // sized so array does not need to realloc as you add stuff to it
You cannot arbitrarily increase the size of the array by indexing past the size - if you have an object at index 5, you can replace it though:
holdsMyClass[5] = obj;
For example, if you try to compile this, it fails:
- (NSArray*[]) createArray
{
NSArray *foo[10];
foo[2] = [NSArray array];
return foo;
}
generates this error: "array initializer must be an initializer list"

Xcode Gives Strange Output From NSArray

When I run this code, the output is some 1084848 to the console. I can't figure out why such odd output... here is the code.
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] init];
int someNumber = 3;
[array addObject:[NSNumber numberWithInt:someNumber]];
NSLog(#"%i" , [array objectAtIndex:0]);
[pool drain];
return 0;
}
the "%i" format specifier expects an integer, not an Object.
Try NSLog(#"%i" , [[array objectAtIndex:0] intValue]);
XCode is probably giving you a warning on this line: something like "Conversion specifies type 'int', but argument has type 'id'".
Here's the pseudocode of your program:
//
// Inside of your main function....
//
// Set up the Autorelease pool and then create an array
//
// Declare an int
//
// Add the int to an array, while wrapping it in an NSNumber
//
// Log the value of the first object in the array, using the int formatter
//
// Clean up and return
//
You are logging the first object in the array, but NSArray cannot hold a primitive that's not wrapped in an Objective-C object.
To better understand your code, try changing these lines of code:
int someNumber = 3;
[array addObject:[NSNumber numberWithInt:someNumber]];
Expand them a little. Try this:
int someNumber = 3;
NSNumber *aNumber = [NSNumber numberWithInt:someNumber];
[array addObject:aNumber];
So, you've correctly wrapped the int in an NSNumber, but you're not unwrapping it. You need to ask your NSNumber for the int that it holds like so:
[[array objectAtIndex:0] intValue];
Or, to do the logging in one line:
NSLog(#"%i" , [[array objectAtIndex:0] intValue]);
The characters "%i" is called a "formatter". Different kinds of values require different formatters. When you are using an Objective-C object, you use "%#". For an NSInteger or int, you'd use %i. For a float, you'd use "%f". The point is that you need to either unwrap that number, or use the Objective-C formatter for strings.
A quick note about that weird value you were getting earlier: That's a memory address in RAM. It's the closest thing you're going to get when you use an incorrect formatter. In some cases, using the wrong formatter will cause an EXC_BAD_ACCESS. You were "lucky" and got a weird value instead of a dead program. I suggest learning about strings and formatters before you move on. It will make your life a lot easier.
When you use %i for integer values then you should give arguments as integer as below
NSLog(#"%i" , [[array objectAtIndex:0] intValue]);
But when you want object to be displayed then you must use %# which identifies object in general case as below:
NSLog(#"%#", array);

Convert NSString to Integer in objective - c

I have an array that stores each digit of a phone number as a string. I then pass the phone number digit string as an argument for objectAtIndex: method of NSArray like this: [myArray objectAtIndex: [myString intValue]]; The compiler says I need to cast the String but I am already doing that. What is wrong?
Update:
Here's my actual line of code:
NSMutableArray *tmp = [[NSMutableArray alloc] initWithArray:[charHolder objectAtIndex:[[phoneNumDigits objectAtIndex:i]intValue]]];
This is where the error is, phoneNumDigits is an array of each digit of the phone number, charHolder is the array holding the array of letters associated with each digit.
Your question is a little confusing to me. Here is how I understand what you want to do:
You have an NSArray named phoneNumDigits. This array contains a few NSString objects. Each string is something like #"1" or #"4" and represents a single digit of a phone number.
Now you want to convert each of those digit strings to int or NSInteger and want to store these integers in another array.
If I understood you correctly, here is my answer:
You cannot exactly do what you want, because you can't put a simple data type like an int or a float into an NSArray.
That's why there is the wrapper class NSNumber. You can package a simple int in an NSNumber and store this NSNumber in an NSArray.
So to get your string digits from the phoneNumDigits into the tmp array you could use this code:
for (NSString *digitAsString in phoneNumDigits)
{
NSNumber *digitAsNumber = [NSNumber numberWithInt:[digitAsString intValue]];
[tmp addObject:digitAsNumber];
}
To get the ints out of the tmp-NSArray you would use
int digit = [[tmp objectAtIndex:idx] intValue];
I hope this helps, but I'm not sure I understand what you want to do here. I could be completely missing the point. Maybe you could share some more code.
NSMutableArray *tmp = [[NSMutableArray alloc] initWithArray:[charHolder objectAtIndex:[[phoneNumDigits objectAtIndex:i]intValue]]];
objectAtIndex returns a generic object (id). It has no idea that the object in the array is a string as it could be anything. So you need to cast it. Or to increase readabilty, create variables for them. Eg:
int phoneNumberDigit = [phoneNumDigits objectAtIndex:i];
NSArray *chars = [charHolder objectAtIndex:phoneNumberDigit];
NSMutableArray *tmp = [[NSMutableArray alloc] initWithArray:chars];

Problem retrieving data from array iphone?

I declared a nsmutablearray and assign some object but when retrieving object it gives memory location.Here is the code.
NSMutableArray *arrCondiNum = [[NSMutableArray alloc] init];
[arrCondiNum addObject:#"2"];
[arrCondiNum addObject:#"4"];
[arrCondiNum addObject:#"6"];
[arrCondiNum addObject:#"8"];
for(int i = 0;i<[arrCondiNum count];i++){
NSLog(#"Array number %d",[arrCondiNum objectAtIndex:i]);
}
Output it gives
Array number 20820
Array number 20836
Array number 20852
Array number 20868
You add string in your array, then to display it, you have to use %#:
NSLog(#"Array number %#",[arrCondiNum objectAtIndex:i]);
In your code (%d), you display the address of the object.
%# will display the description of the ObjC object (return of -descriptionWithLocale: or -description)
Note that in case you want an array of numbers, use NSNumber instead:
[array addObject:[NSNumber numberWithInt:1]];
You still have to use the %# format specifier though (as NSNumber is a class-type) or retrieve the integer value using -intValue.
Try [[arrCondiNum objectAtIndex:i] floatValue] instead. NSArrays are keeping objects (pointers to objects to be more precise), not values. So the array will return the string object you created earlier. By sending this object the "floatValue" message, it will return its content represented as float value. You could use intValue as well to receive an integer.
just write like this..
NSLog(#"Array number %#",[arrCondiNum objectAtIndex:i]);
u have to print some text..so