I'm trying to add values to the yArray. However in the NSLog, it always shows up null. I am synthesizing the NSMutableArray (yArray) and get no errors or warnings on compiling. I believe one reason might be that i am not initializing the array. I read somewhere that #synthesize does not initialize. However, i'm a beginner and i'm not sure how to properly initialize the array. I've researched it on google but couldn't figure it out. Can someone tell me how or at least point me in the right direction. I posted a part of my code below. Thank you in advance.
for (int i = 0; i < n; ++i)
{
xx = xx + [[self.yArr1 objectAtIndex:i] doubleValue];
}
for (int i = 0; i < n; ++i)
{
if(i==0)
[self.yArray addObject:[NSNumber numberWithDouble:(0.0)]];
else
{
bb = fabs([[self.yArr1 objectAtIndex:i] doubleValue]- [[self.yArr1 objectAtIndex:(i-1)] doubleValue]);
[self.yArray addObject:[NSNumber numberWithDouble:(bb)]]; // This is the problem.
yy = yy + [[self.yArray objectAtIndex:i] doubleValue];
}
NSLog(#"prediction %f, %f, %#, %f", bb, yy, [self.yArray objectAtIndex:i],[[self.yArr1 objectAtIndex:i] doubleValue]);
}
NSLog(#"prediction %f, %f", bb, yy);
To properly initialize the array use
NSMutableArray* yArray = [[NSMutableArray alloc] init];
Initialize it before using it (maybe in init method or something like that), then retry. Don't forget to manually release it when you have done.
Just initialize it first in a location that will be hit prior to your addObject code. e.g.
yArray = [[NSMutableArray alloc] init];
Related
I have two codes. Not working is the following:
NSMutableArray *tmpArray = [[NSMutableArray alloc] init];
for (int i=0; i<[dataSetArray count]; i++) {
tmpArray = (NSMutableArray *) [dataSetArray objectAtIndex:i];
// OR use: tmpArray = dataSetArray[i]
... doing stuff
[tmpArray replaceObjectAtIndex:0 withObject:tmpStr];
}
While this works:
for (int i=0; i<[dataSetArray count]; i++) {
NSMutableArray *tmpArray = [[NSMutableArray alloc] initWithArray:[dataSetArray objectAtIndex:i]];
... doing stuff
[tmpArray replaceObjectAtIndex:0 withObject:tmpStr];
}
Two questions:
The first code doesn't yield an NSMutableArray. Why? I declare it
above.
Is there a better way to obtain the same result. I just
dislike defining variables in a loop. This makes the code
unreadable.
--- edit:
Here the full code:
Datatypes are:
dataSetArray: NSMutableArray. However, its contents (i.e. dataSetArray[i]) are NSArrays (I read them into the program from an excel file).
NSString *tmpStr = [[NSString alloc] init];
for (int i=0; i<[dataSetArray count]; i++) {
NSMutableArray *tmpArray = [[NSMutableArray alloc] initWithArray:[dataSetArray objectAtIndex:i]];
for (int j=0; j<[tmpArray count]; j++) {
if ( [dataSetArray[0][j] isEqualToString:#"Number"] ) {continue;}
tmpStr = (NSString *) [tmpArray objectAtIndex:j];
// replace single backslash by double-backslash:
tmpStr = [tmpStr stringByReplacingOccurrencesOfString:#"\\" withString:#"\\\\"];
// replace first dollar sign by "<p>\\[" and second by "\\]</p>"
// Use a methode defined in the NSString+Extension
tmpStr = [tmpStr replaceTexFormulaSigns:tmpStr];
//NSLog(#"j=%d", j);
//NSLog(#"tmpArray is of type: %#", [tmpArray class]);
//NSLog(#" tmpStr is of type: %#", [tmpStr class]);
[tmpArray replaceObjectAtIndex:j withObject:tmpStr];
}
[dataSetArray replaceObjectAtIndex:i withObject:tmpArray];
}
So even if I use your suggestion, I am still facing the same problem with the inner array.
The first code doesn't yield a NSMutableArray. Why? I declare it above.
The declaration of the reference variable tmpArray does not change the type of the referred object. It is still an (immutable) array.
The creation of the mutable array at the very beginning of the first snippet is without any meaning, because the reference to it is overridden.
Is there a better way to obtain the same result. I just dislike defining variables in a loop. This makes the code unreadable.
Yes. The second example works in a way, but do something completely different. (It always creates a new array with a single item in it. No, that's not true. It shouldn't compile at all.)
You should do:
NSMutableArray *tmpArray = [dataSetArray mutableCopy];
for (int i=0; i<[dataSetArray count]; i++)
{
…
[tmpArray replaceObjectAtIndex:i withObject:tmpStr];
}
You should really get some additional knowledge about objects and object references.
I'm trying to add objects to NSMutableArray (categoriasArray), but its not done by the iterator:
#synthesize categoriasArray;
for (int i = 0; i < [categories count]; i++) {
categoria *cat = [[categoria alloc] initWithDictionary:[categories objectAtIndex:i]];
[self.categoriasArray addObject:cat];
cat=nil;
}
After the for iterator, categoriasArray has 0 objects.
Many thanks
Check that the array is not nil before the loop starts:
NSLog(#"%#", self.categoriasArray); // This will output null
for (int i = 0; i < [categories count]; i++) {
// ...
}
What you should understand is that synthesizing the property categoriasArray doesn't initialize it, it just generates the setter and the getter methods. So, to solve your problem, initialize the array before the loop, (or in the init method of your class):
self.categoriasArray = [[NSMutableArray alloc] init];
The other possibility is that categories is itself nil or doesn't contain any items. To check that, add NSLogs before the loop:
NSLog(#"%#", self.categoriasArray);
NSLog(#"%#", categories);
NSLog(#"%d", [categories count]);
for (int i = 0; i < [categories count]; i++) {
// ...
}
try this
for(categoria *cat in categoria){
[self.categoriasArray addObject:cat];
// check you go here or not
}
I would advise getting in the habit of initializing your arrays with autorelease formatting such as the following.This is not only less to type but also good practice for mem management purposes. Of course if you are using ARC then both will work. This goes the same for NSString and many others (i.e. self.categoriasString = [NSMutableString string];)
self.categoriasArray = [NSMutableArray array];
Afterword you can add objects to that array by calling [self.categoriasArray addObject:cat];
I’ve recently stuck at a problem. Here is the thing, I’m trying to get a float object from NSArray that holds it, and all I can get is (null). Obviously not the thing that I want to receive. Look at the snippet of code:
h = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithFloat:1.0],[NSNumber numberWithFloat:1.0],[NSNumber numberWithFloat:1.0], nil];
x = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithFloat:1.0],[NSNumber numberWithFloat:2.0], nil];
y = [[NSMutableArray alloc] init];
int step = 15; // That is just a random value, will depend on size of h and x.
for (int i = 0; i < step; ++i) {
NSLog(#"step = %i", i);
NSMutableArray *xTemp = [[NSMutableArray alloc] initWithArray:x];
NSMutableArray *hTemp = [[NSMutableArray alloc] initWithArray:h];
for (int j = 0; j < 3; ++j) {
float xToMul = [[xTemp objectAtIndex:j] floatValue];
float hToMul = [[hTemp objectAtIndex:(j+i)] floatValue];
NSLog(#"xToMul = %#", xToMul);
NSLog(#"hToMul = %#", hToMul);
}
NSLog(#"\n");
}
And the resul is:
xToMul = (null)
hToMul = (null)
and all I need those values is to do some easy math.
Thanks.
M.R.
Here's your problem:
float xToMul = [[xTemp objectAtIndex:j] floatValue]; float hToMul = [[hTemp objectAtIndex:(j+i)] floatValue];
NSLog(#"xToMul = %#", xToMul); NSLog(#"hToMul = %#", hToMul);
%# is for objects that support -description. float is not an object at all. This code sends the float a -description message, which it can't respond to.
There's two ways to solve this.
The first is to make xToMul and hToMul objects instead of floats and keep the format string.
id xToMul = [xTemp objectAtIndex:j];
id hToMul = [hTemp objectAtIndex:(j+i)];
NSLog(#"xToMul = %#", xToMul);
NSLog(#"hToMul = %#", hToMul);
The second is to keep them as floats but fix the format string:
float xToMul = [[xTemp objectAtIndex:j] floatValue];
float hToMul = [[hTemp objectAtIndex:(j+i)] floatValue];
NSLog(#"xToMul = %f", xToMul);
NSLog(#"hToMul = %f", hToMul);
If you're planning to do math with the floats, you probably want to pick this option.
Another interesting point is this loop:
for (int j = 0; j < 3; ++j) {
This will step through j with three values: 0, 1 and 2. That corresponds to the first, second and third item in NSArray. You have two items in x and three in h. I'm guessing this is just a simplification of your original code, but in both cases it's one short. j of 2+1 will access the 4th item in h, and j of 2 will access the 3rd item in x.
self.myArray = [NSArray arrayWithObjects: [NSArray arrayWithObjects: [self generateMySecretObject], [self generateMySecretObject],nil], [NSArray arrayWithObjects: [self generateMySecretObject], [self generateMySecretObject],nil],nil];
for (int k=0; k<[self.myArray count]; k++) {
for(int s = 0; s<[[self.myArray objectAtIndex:k] count]; s++){
[[[self.myArray objectAtIndex:k] objectAtIndex:s] setAttribute:[self generateSecertAttribute]];
}
}
As you can see this is a simple 2*2 array, but it takes me lots of code to assign the NSArray in very first place, because I found that the NSArray can't assign the size at very beginning. Also, I want to set attribute one by one. I can't think of if my array change to 10*10. How long it could be. So, I hope you guys can give me some suggestions on shorten the code, and more readable. thz
(Some Assumptions: myArray will have a fixed size. It won't grown up or become smaller in the run time.)
Generate the array by -addObject:.
NSMutableArray* myArray = [NSMutableArray array];
for (int k = 0; k < 10; ++ k) {
NSMutableArray* subArr = [NSMutableArray array];
for (int s = 0; s < 10; ++ s) {
id item = (s == 0 && k == 0) ? [self d] : [self generateMySecretObject];
[item setAttribute:[self generateSecertAttribute]];
[subArr addObject:item];
}
[myArray addObject:subArr];
// use [myArray addObject:[[subArr copy] autorelease]] for deep immutability.
}
return [[myArray copy] autorelease];
(Don't query self.myArray many times. Each corresponds to an ObjC call and while someone calls an ObjC call is cheap, it's still not free.)
If the array is a fixed size and each row is the same length then you could uses a 1D array and an offset, EG:
int rowLength = 5;
int rowNumber = 0;
int columnNumber = 3;
[myArray objectAtIndex: (rowLength * rowNumber) + columnNumber];
I used to be a Java Programmer, which the array need to declare the very first time, like this:
int[] anArray; // declares an array of integers
anArray = new int[10]; // allocates memory for 10 integers
I don't know whether the Objective C , NSMutableArray also give me this ability or not. Actually, I want to make a 10*10 array. thz in advance.
I try to do this:
myArray = [[NSMutableArray alloc] initWithCapacity:10];
for (int i=0; i<10; i++) {
myArray[i] = [[NSMutableArray alloc] initWithCapacity:10];
}
But it occurs errors, telling my incompatible type assignment.
The capacity field is seldom useful. The array will be expanded on demand anyway.
And the capacity field just tells the array how much memory you may use. The array's length is still 0.
But you can grow the array from empty:
for (int i = 0; i < 10; ++ i)
[myArray addObject:…];
To read and write to an element in an NSMutableArray, you need:
id x = [array objectAtIndex:i]; // x = array[i];
[array replaceObjectAtIndex:i withObject:y]; // array[i] = y;
You cannot subscript an NSArray directly.
Your code has memory leak. Unlike Java, ObjC doesn't use a GC unless you explicitly enable it (and ObjC on iPhoneOS doesn't have GC). ObjC manages memory by manual reference counting. Basically you need to ensure the ref count of stuff you don't own doesn't change in the process. See http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html for detail.
In your case, [[NSMutableArray alloc] …]; creates an object of ref count +1, then the assignment will take over the array, that means you don't own it any more, but the ref count is not balanced to 0, so this memory will not be properly deallocated. You need to use convenient methods such as [NSMutableArray array…] to create an object with ref count 0.
NSArray's can only store ObjC objects. int in C (ObjC) is a primitive, and cannot be stored into an NSArray. You have to box it into an NSNumber by [NSNumber numberWithInt:0]. You can get back the integer with -intValue.
To conclude, your code needs to be modified as:
-(NSMutableArray*)get10x10Array {
NSMutableArray* arr = [NSMutableArray array];
for (int i = 0; i < 10; ++ i) {
NSMutableArray* subarr = [NSMutableArray array];
for (int j = 0; j < 10; ++ j)
[subarr addObject:[NSNumber numberWithInt:0]];
[arr addObject:subarr];
}
return arr;
}
But ObjC is a superset of C. You can just use a plain 10x10 C array.
int arr[10][10];
You want a 10x10 array -- of what?
myArray = [[NSMutableArray alloc] initWithCapacity:10];
for (int i=0; i<10; i++) {
myArray[i] = [[NSMutableArray alloc] initWithCapacity:10];
}
But it occurs errors, telling my
incompatible type assignment.
Because you can't assign to myArray like that. myArray is an object that represents an array data structure. It is not a C array.
If you want a 10x10 array of a primitive data type, you can declare one like you would in C:
int myArray[10][10];
initWithCapacity: is what you want. It may look like
NSMutableArrat *array = [[NSMutableArray alloc] initWithCapacity:10];
You can't access Cocoa array objects with the bracket notation. Your second bit of code should be:
NSMutableArray *myArray = [[NSmutableArray alloc] initWithCapacity:10];
for (int i = 0; i < 10; i++) {
[myArray insertObject:[NSMutableArray arrayWithCapacity:10] atIndex:i]; // Note: not using myArray[i]!
}
There are two ways to do this.
Plain old C
If you want to store objects, you should use the id type instead of int.
int myarray[10][10];
myarray[5][2] = 412;
Objective-C
NSArray's are not meant to have spaces without objects, if you need them you could use [NSNull null], but if that's the case a C array would be better anyway.
NSMutableArray *myArray = [[NSMutableArray alloc] initWithCapacity:10];
for (int i=0; i < 10; i++) {
NSMutableArray *innerArray = [[NSMutableArray alloc] initWithCapacity:10];
for (int j=0; j < 10; j++) {
[innerArray addObject:[NSNull null]];
}
[myArray addObject:innerArray];
[innerArray release];
}
[[myArray objectAtIndex:5]
replaceObjectAtIndex:2 withObject:[NSNumber numberWithInteger:123]];
NSArray objects have a fixed size that cannot be changed once they have been initialised. NSMutableArray objects can change size. A 10×10 array is sometimes implemented as an NSArray containing 10 individual NSArray objects, each of these containing ten items. This quickly gets cumbersome, sometimes it is easier to resort back to plain C for such a task:
int tenByTen[10][10];
Or, you can use this:
typedef struct
{
int y[10];
} TenInts;
typedef struct
{
TenInts x[10];
} TenByTen;
Then you could do:
- (void) doSomethingWithTenByTen:(const TenByTen) myMatrix
{
NSLog ("%d", myMatrix.x[1].y[5]);
}
And you can also return them from methods:
- (TenByTen) mangleTenByTen:(const TenByTen) input
{
TenByTen result = input;
result.x[1].y[4] = 10000;
return result;
}
You want NSMutableArray +arrayWithCapacity:
Note that setting the initial capacity is merely an optimization - Mutable arrays expand as needed.
EDIT:
To do the 10x10 case,
myArray = [[NSMutableArray alloc] initWithCapacity:10];
for (int i=0; i<10; i++) {
NSMutableArray *subArray = [NSMutableArray arrayWithCapacity:10];
[myArray addObject:subArray];
for (int j = 0; j<10; j++) {
[subArray addObject:[NSNumber numberWithInt:0]];
}
}
Notes:
an array retains the objects added to it, so its not necessary to retain subArray
only objects (not primitive types like "int") can be added to an NSArray, hence the need for NSNumber numberWithInt:
you use methods like objectAtIndex: and replaceObjectAtIndex:withObject: to get/set a value from an NSArray, not array subscript ([]) syntax
See Apple refs for NSArray and NSMutableArray
You can use the following code to resize the NSMutableArray once it was created:
#interface NSMutableArray (Resizing)
- (NSMutableArray *)resize:(NSInteger)newSize;
#end
#implementation NSMutableArray (Resizing)
- (NSMutableArray *)resize:(NSInteger)newSize
{
int size = (newSize > [self count]) ? self.count : newSize;
NSMutableArray *array = [NSMutableArray arrayWithCapacity:size];
for (int i = 0; i < size; i++){
[array addObject:[self objectAtIndex:i]];
}
return array;
}
#end