problem with NSMutableArray

Hello,


I'm a new one here but I want to learn.

I'm trying to use NsMutableArray.

For this I create a code which permit to take one by one pixel from a picture and put the RBG color of each pixel in a NsMutableArray.

Everything works fine except at the end. Indeed after fill each RGB color of each pixel, my NsMutableArray is empty (after the for loop).

Does anyone have an idea why it is reset? THanks


I put the code below. To make it easy to read, I've removed the table blue and greem. I put only red table.


Thanks for your help


NSMutableArray * ligneR = [[NSMutableArray alloc] init];
NSMutableArray * colonneR = [[NSMutableArray alloc] init];

for (NSUInteger i = 0; i < ghostSize.width; i++) {
     [colonneR addObject:[[NSMutableString alloc]init ]];
}
for (NSUInteger j = 0; j < ghostSize.height; j++) { 
     for (NSUInteger i = 0; i < ghostSize.width; i++) { 
          UInt32 * inputPixel = inputPixels + j * inputWidth + i + offsetPixelCountForInput; 
          UInt32 inputColor = *inputPixel; 
          UInt32 * ghostPixel = ghostPixels + j * (int)ghostSize.width + i; 
          UInt32 ghostColor = *ghostPixel; 
          int newR = R(ghostColor) ;


          NSNumber *R=[NSNumber numberWithInt:newR]; 
          [colonneR replaceObjectAtIndex:i withObject:R];


          *inputPixel = RGBAMake(newR, newG, newB, A(inputColor)); 
     } 
     [ligneR addObject:colonneR]; 
}

Which array is empty, ligneR or colonneR? How did you determine it was empty?


Could you be confusing a local variable for a property or instance variable of the same or similar name?


Are you sure that neither ghostSize.width nor ghostSize.height are zero?


Besides the problem with the array being empty, the code has a problem. You are repeatedly adding colonneR to the ligneR array. Adding an object to an array does not make a copy, it just adds a reference to that object to the array. So, there's only one object in ligneR, but it's been added multiple times. Each time through the inner loop, you modify the contents of that one object. So, you are modifying the contents of the object all all indexes of ligneR. That is, ligneR[0] is the same exact object as ligneR[1] and ligneR[2], etc. All of them are the same as colonneR. When you modify colonneR, you're modifying that same object that's held at every index of ligneR.

Hi,


Thanks for your quick answer.


It is ligneR which is empty.

In fact I'm using breakpoint to see the behaviour of my variable.

No I'don't have similar name.

ghostSize.width and ghostSize.height are respectively set to 471 and 171.


Ok I undertsand what you say in the last part. Indeed what I want is to put each pixels in a "table" and I learn that table is not available in objective C. So I was thinking I can use two NsMutableArray (one of 171 and another to 471) to represent each pixel in the combination of the two NsMutableArray. Like this my pixels will be at his exact width and height.

Using debogguer I see that my two NsMutableArray is filled with the value (i.e. 255 ) So I succeed to have a representation of all the pixels. But when I put a bearkpoint after the for loops, my NSMutableArray is set to 0.

But I think your right, there is somewhere I must modify the content of the object. I will look at this.


THank very much.

As Ken says, you should be adding [colonneR copy] (or mutableCopy if you need to modify it later) to ligneR to ensure that all the entries in ligneR refer to distinct array instances, not all pointing to the same column array repeated many times.


But the array cannot magically become empty... I suspect the problem may be in the code that you have omitted in order to make it "easier to read" 🙂


Do you have a property named ligneR? Is it that property that is "0" (whatever that means)? Again, as Ken pointed out, your code snippet is declaring a *local variable* named ligneR; all of that code would affect only the local variable, not the property, if that was your intention.

Keep in mind that a 2 dimensional set of numbers can be stored in a two dimensional C array like N[171][471] or a NSMutableArray that contains 471 NSMutableArrays each with 171 NSNumbers but it cannot be contained in "two NSMutableArrays..." as you stated.

This will accomplish what you want. ligneR will become a mutable array containing ghostSize.width objects where each object in ligneR is an NSMutableArray containing ghostSize.height NSNumbers. (I also included turning ligneR into a C array which is easier to understand, IMHO)



NSMutableArray * ligneR = [[NSMutableArray alloc] init];
NSMutableArray * colonneR = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < ghostSize.width; i++) {
     [colonneR addObject:@"any **** thing here"];
}
//   or replace the five lines above with:
//   int ligneR[ghostSize.width][ghjostSize.height];


for (NSUInteger j = 0; j < ghostSize.height; j++) {
     for (NSUInteger i = 0; i < ghostSize.width; i++) {

   // I have no idea if the next few lines do what you want
          UInt32 * inputPixel = inputPixels + j * inputWidth + i + offsetPixelCountForInput;
          UInt32 inputColor = *inputPixel;
          UInt32 * ghostPixel = ghostPixels + j * (int)ghostSize.width + i;
          UInt32 ghostColor = *ghostPixel;
          int newR = R(ghostColor) ;
      // I have no idea whethere the stuff above will grab the i,j element in your image but assume it has

          NSNumber *Rxxx=[NSNumber numberWithInt:newR];
          [colonneR replaceObjectAtIndex:i withObject:Rxxx];

//       or replace the two lines above and the addObject line below with:
//            ligneR[i][j]=newR;



//          *inputPixel = RGBAMake(newR, newG, newB, A(inputColor));
     }
     [ligneR addObject:[colonneR copy]];
}

Thanks for all your answer.

I'm at work now but I will look at this later.


Thanks for all the information, it will be very helpfull.

I will keep you in touch.

problem with NSMutableArray
 
 
Q