Sum two NSInteger gives incorrect result - objective-c

Im haveing a problem suming two NSInteger, I have tried with simple int but cant find the answer. I Have this on my header file:
#interface ViewController : UIViewController {
NSMutableArray *welcomePhotos;
NSInteger *photoCount; // <- this is the number with the problem
//static int photoCount = 1;
}
The on my implementation fiel I have:
-(void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
photoCount = 0;
welcomePhotos = [NSMutableArray array];
int sum = photoCount + 1;
NSLog(#"0 + 1 = %i", sum);
}
The las NSLog always prints 0 + 1 = 4
Also if if do:
if (photoCount < [welcomePhotos count]){
photoCount++;
NSLog(#"%i", photoCount);
}else{
photoCount = 0;
}
Several times i get: 4, 8, 12.
So it is skiping by four, but I can't get to understand why.

You are declaring your photoCount instance var as pointer to NSInteger. But NSInteger is a scalar type.
Remove the asterisk in your .h file and try again.
Replace
NSInteger *photoCount;
with
NSInteger photoCount;

You're printing out a pointer object I believe as you've declared it as
NSInteger* photocount;
Try changing it to
int photocount;
doing a variable++ on an integer adds the size of a pointer which is 4 bytes on iOS.

You used pointer to NSInteger...
Change it to NSInteger photoCount;
NSInteger is just an int, and you are treating it as an wrapper object. Pointer in not required.

Related

Why would a function defined in the same class be considered undeclared? How to declare it properly?

I'm getting the error "undeclared identifier" on the commented line:
- (BOOL) isInIntArray:(NSInteger[])array theElem:(int)elem{
int i = 0;
NSInteger sizeOfArray = (sizeof array) / (sizeof array[0]);
while(i < sizeOfArray){
if(array[i] == elem){
return TRUE;
}
i++;
}
return FALSE;
}
- (int)getNextUnusedID{
int i = rand()%34;
while ([isInIntArray:idsUsed theElem:i]) { //here: Use of undeclared identifier 'isInIntArray'
i = rand()%34;
}
return i;
}
I really don't understand why, they are in the same .m file.
Why would that be?
Also, this code:
NSInteger sizeOfArray = (sizeof array) / (sizeof array[0]);
is giving me the warning:
Sizeof on array function will return Sizeof 'NSInteger *' (aka: 'int *') instead of 'NSInteger[]'"
How should I properly determine the size of an array?
It looks like you've missed out self from this line
while ([isInIntArray:idsUsed theElem:i])
This should be:
while ([self isInIntArray:idsUsed theElem:i])
As #CaptainRedmuff pointed out, you are missing the target object in method invocation, that is self.
//[object methodParam:x param:y];
[self isInIntArray:idsUsed theElem:i];
To your second Q. In C language you cannot determine the size of an array. That's why they are not used, since we have objects for this. I recommend you to use these:
NSMutableArray *array = [[NSMutableArray alloc] init]; // to create array
array[0] = #42; // to set value at index, `#` creates objects, in this case NSNumber
[array insertObject:#42 atindex:0]; // equivalent to the above
NSInteger integer = array[0].integerValue; // get the value, call integerMethod to get plain int
integer = [[array objectAtIndex:0] integerValue]; // equivalent to the above
[array containsObject:#42]; // test if given object is in the array
[array indexOfObject:#42]; // get index of object from array, NSNotFound if not found
array.count; // to get the number of objects
Important: These arrays have variable size and they are not limited! But you can access elements only at indexes 0..(n-1) (where n in number of objects) and you can set values only for indexes 0..n.
In other words, you can not do array[3] = #42; for empty array, you need to fill first 3 positions first (indexes 0, 1 and 2).
write this in .h file (declare the function)
- (BOOL) isInIntArray:(NSInteger[])array theElem:(int)elem;
and call the method using following way
while ([self isInIntArray:idsUsed theElem:i]) { //here: Use of undeclared identifier 'isInIntArray'
i = rand()%34;
}

NSFastEnumeration crashing on C array with ARC

I'm initializing a C array of objects and setting the first element:
id __strong *_objs = (id __strong *)calloc(16,sizeof(*_objs));
_objs[0] = #1;
_count++;
Then I'm using the following implementation of NSFastEnumeration:
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
objects: (id __unsafe_unretained*)stackbuf
count: (NSUInteger)len
{
NSUInteger size = _count;
NSInteger count;
state->mutationsPtr = (unsigned long *)size;
count = MIN(len, size - state->state);
if (count > 0)
{
IMP imp = [self methodForSelector: #selector(objectAtIndex:)];
int p = state->state;
int i;
for (i = 0; i < count; i++, p++) {
stackbuf[i] = (*imp)(self, #selector(objectAtIndex:), p);
}
state->state += count;
}
else
{
count = 0;
}
state->itemsPtr = stackbuf;
return count;
}
Unfortunately it crashes with EXC_BAD_ACCESS when I run it:
for (id object in array){ // EXC_BAD_ACCESS
NSLog(#"%#",object)
}
Any idea why?
If you have CodeRunner, here is an executable version.
The problem is the mutationsPtr which points to the memory address 1 which you are not allowed to access (and which is not 4 byte aligned as well):
state->mutationsPtr = (unsigned long *)size;
Replace it with a valid pointer for starters (careful: the one below may make no sense at all in your scenario, but at least it fixes the EXC_BAD_ACCESS):
state->mutationsPtr = (unsigned long *)&_count;
#Jano
In case you want to get rid of the compiler warning you will get with recent versions of Xcode (4.6) for
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
objects: (id __unsafe_unretained*)stackbuf
count: (NSUInteger)len
because it does not match the original prototype for objects:..stackbuf
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
objects: (__autoreleasing id *)stackbuf
count: (NSUInteger)len
see Todd Lehmans answer in Automatic Reference Counting: Error with fast enumeration

Create an global array containing floating numbers

I wanted to create 2 global arrays which can be updated during the run of the programme.In each update i add one element to zeroth position and deleted the last number
I created the arrays as....
In the .h file..........
//////////////
#interface Shared : NSObject{
NSMutableArray *x;
NSMutableArray *y;
}
#property (nonatomic,retain) NSMutableArray *x;
#property (nonatomic,retain) NSMutableArray *y;
+(Shared*)sharedInstance;
#end
In .m file
staticShared* sharedInstance;
#implementation Shared
#synthesize x;
#synthesize y;
+(Shared*)sharedInstance
{
if (!sharedInstance) {
sharedInstance=[[Sharedalloc]init];
}
returnsharedInstance;
}
-(Shared*)init
{
self = [superinit];
if(self)
{
x=[[NSMutableArrayalloc] init];
x=[NSMutableArrayarrayWithObjects:#"0",#"0",#"0",#"0",#"0",#"0",#"0",nil];
y=[[NSMutableArrayalloc] init];
y=[NSMutableArrayarrayWithObjects:#"0",#"0",#"0",#"0",#"0",#"0",nil];
}
returnself;
}
#end
Then i used to call them and re,ove and added elements using the following code....
[[shared sharedInstance].y removeLastObject];
[[shared sharedInstance].y insertObject:new_element atIndex:0];
[[shared sharedInstance].x removeLastObject];
[[shared sharedInstance].x insertObject:new_element atIndex:0];
In the mean time i call these values and calculate an arithmetic value using an expression.
This seems to work well. But it seems to be an inefficient way to handle floating point numbers which i store in it. As these arrays creates objects. Is there any easy method that i can create a global array containing specified amount of floating point numbers and update it during the run of the programm(array size is fixed) by deleting the last object, and call them back to do calculation?
Please help me!
EDIT 1
To sir deanWombourne
.................................
I implement as you instructed! Can you please go through this and help me to correct 2 errors i get.
IN the .h file
#interface Shared : NSObject{
#private
float input[7];
float output[6];
}
+(Shared*)sharedInstance;
-(void)addNewInput:(float)input1;
-(float *)input;
-(void)addNewOutput:(float)output1;
-(float *)output;
#end
in .m file............
#implementation Shared
-(id)init{
if((self =[superinit])){
for(int n=0; n<7 ;++n)
input[n]=0.00f;
for(int n=0; n<6 ;++n)
output[n]=0.00f;
}
returnself;
}
-(void)addNewInput:(float)input1{
input[0]=input[1];
input[1]=input[2];
input[2]=input[3];
input[3]=input[4];
input[4]=input[5];
input[5]=input[6];
input[6]=input1;
}
-(float *)input {
returninput;
}
-(void)addNewOutput:(float)output1{
output[0]=output[1];
output[1]=output[2];
output[2]=output[3];
output[3]=output[4];
output[4]=output[5];
input[5]=output1;
}
-(float *)output {
returnoutput;
}
#end
When calling it
float reading= (accel_reading)/(1.165969038*1e5f);
[[SharedsharedInstance] addNewInput:reading];
Problems i get
1. In the implementation, it says incomplete implementation (it's a warning not an error)
2. How can i used a for loop to fill array values or is this way ok?
Major problem i get,
When i call it as shown above, program stops running telling
Terminating application due to uncaught exception 'NSInvalidArgumentException', reason '+[SharedsharedInstance]: unrecognized selector sent to class 0x5780'
Please help me through this...............
Your code Smells (and I mean that in the nicest possible way!)
Using two parallel arrays and keeping in sync is a bad design pattern (and a performance hit in quite a few ways!). Especially as there is already a struct that handles storing an x and y at the same time - CGPoint).
You're solving the 'only objects go in arrays' problem by converting your float' primitives toNSString` objects, which is horrendously inefficient - take a look instead at the NSValue class, it's designed to put native C primitives into an object without expensive parsing operations :)
You might also want to look into malloc (and free etc) and deal with the whole problem at the C level - this will mean no objects at all and would be blindingly fast (at the cost of more complicated code).
Hope this helps, if you have any questions just add a comment to this answer :)
EDIT
If all you want to do is store 4 x and y values, then this is probably the easiest way to do it :
#interface Shared : NSObject {
#private
CGPoint points[4];
}
+(Shared *)sharedInstance;
- (void)addNewPoint:(CGPoint)point;
- (CGPoint *)points;
#end
#implementation
- (id)init {
if ((self = [super init])) {
// Start with 0,0 for all your points
for (int n = 0; n < 4; ++n)
points[n] = CGPointZero;
}
return self;
}
- (void)addNewPoint:(CGPoint)point {
// Just move all the points along one and add the new one to the end
// (yes, this could be done in a loop but there's not that much point for 4 points!)
points[0] = points[1];
points[1] = points[2];
points[2] = points[3];
points[3] = point;
}
- (CGPoint *)points {
return points;
}
#end
This gives you a method addNewPoint that removes the first point and adds the new point to the end of your array.
You also get the method points that returns the 4 points. Use it something like :
// To add a point
CGPoint newPoint = CGPointMake(100, 100);
[[Shared sharedInstance] addNewPoint:newPoint];
// To do something with the points (in this case, NSLog them)
CGPoint *points = [[Shared sharedInstance] points];
for (int n = 0; n < 4; ++n)
NSLog(#" Point %i : %#", n, NSStringFromCGPoint(points[n]));
EDIT #2
From your comments, you need two arrays, one with input data and one with output data. Try something like this :
#interface Shared : NSObject {
float inputs[4];
float outputs[5];
}
...
This will give you two arrays to read/write to - one called inputs and the other called outputs. Access them in pretty much the same way you did the ones in my first edit :
float *inputs = [[Shared sharedInstance] inputs];
for (int n = 0; n < 4; ++n)
NSLog(#" Input %i : %f", n, inputs[n]);
float *outputs = [[Shared sharedInstance] outputs];
for (int n = 0; n < 5; ++n)
NSLog(#" Output %i : %f", n, output[n]);
Would a linked list be overkill for what you're trying to achieve? It's not quite as simple as a static array of floats, but makes the removal of the last object and insertion of the zeroth object reasonably simple and fast.
If you want an array containing a specific number of Objects, you can use NSArray, which is static, opposed to NSMutableArray.
As for the array being Global, just implement a singleton class that contains the 2 arrays and provides the associated methods.
in Globals.h:
#interface Globals : NSObject
+ (Globals *) sharedGlobals;
#end
in Globals.m:
#implementation Globals
static Globals *sharedGlobals = nil;
+ (Globals *) sharedGlobals{
#synchronized(self){
if (sharedGlobals == nil){
sharedGlobals = [[self alloc] init];
}
}
return sharedGlobals;
}
you then can access the arrays (after you implemented them) with the following line:
[[Globals sharedGlobals] getArrayX];
Here is a sketch to get you going.
Your array size is fixed and only contains floating point numbers, start with a C array:
double x[] = {0, 0, 0, 0, 0, 0, 0};
double y[] = {0, 0, 0, 0, 0, 0};
The number of elements in these arrays can be calculated rather than hard-coded:
int xCount = sizeof(x)/sizeof(double);
int yCount = sizeof(y)/sizeof(double);
Now use these arrays as a circular buffer, declare a cursor and initialise:
int xCursor = 0;
The item at the front of the queue is at the cursor:
valueAtFrontOfQueue = x[xCursor]; // get the current front item
To remove the value at front and add a new one to the rear replace the value at the cursor with the new value and increment the cursor:
x[xCursor] = newValueForBackOfQueue; // replace it with new item for back of queue
xCursor = (xCursor + 1) % xCount; // and advance cursor using mod arithmetic to it cycles around
No wrapping doubles as objects, no dynamic allocation at all.
Wrap the above up as you see fit, maybe as a class, and you're done.

Random generator Objective-C

I've declared a static array of integer from 1 to 5 and now want to call randomly each number with each press of a button. I don't want the same number to be called twice.
int randomNumber;
static int size = 5;
int position = arc4random() % size - 1;
randomNumber = usedNumbers[position];
int switcher = usedNumbers[size]; // wrong
usedNumbers[position] = usedNumbers[size];
size--;
usedNumbers[position] = switcher;
Here's what I've done so far. There's a hole in my logic somewhere and I could do with some help. I think it's something to do with the switcher which is trying to hold a number whilst another is being deleted.
If all you want to do is to show a random number every time the button is clicked, here is some code that can help.
But first, the line you use to create the position is wrong. Do this instead:
int position = (arc4random() % 5) + 1; // Creates a random number between 1 and 5.
int position = (arc4random() % 5) - 1; // Creates a random number between -1 and 3.
Second, I'd suggest to use an NSArray or NSMutableArray to hold your data.
I assume that you have a method that is called when you press a button. Inside that method you can simply put something like this:
int size = 5; // You might want to get the size of your array dynamically, with something like [usedNumbers count];
int position = (arc4random() % size) + 1; // Generates a number between 1-5.
NSNumber *randomNumber = [usedNumbers objectAtIndex:position]; // Here is your random number from the array.
So.. If you add the array as an instance variable to your class, your header file would look something like this:
#interface MyViewController : UIViewController
#property (nonatomic, retain) NSMutableArray *usedNumbers;
- (IBAction)buttonWasClicked:(id)sender; // Remember to connect it to your button in Interface Builder.
#end
And your implementation file:
#implementation MyViewController
#synthesize usedNumbers;
- (void)viewDidLoad {
// Initialize your array and add the numbers.
usedNumbers = [[NSMutableArray alloc] init];
[usedNumbers addObject:[NSNumber numberWithInt:4]];
[usedNumbers addObject:[NSNumber numberWithInt:13]];
// Add as many numbers as you'd like.
}
- (IBAction)buttonWasClicked:(id)sender {
int size = [usedNumbers count];
int position = (arc4random() % size); // Generates a number between 0 and 4, instead of 1-5.
// This is because the indexes in the array starts at 0. So when you have 5 elements, the highest index is 4.
NSNumber *randomNumber = [usedNumbers objectAtIndex:position]; // The number chosen by the random index (position).
NSLog(#"Random position: %d", position);
NSLog(#"Number at that position: %#", randomNumber);
}
#end
If you do it like this, a random number will be chosen from the array every time the button is clicked.
Also, remember to release all your objects if you don't have ARC enabled.
PS: There are several other questions here on SO covering this subject. Remember to search before asking.
Update:
To make sure every number is used only once, you can remove it from your array when it is chosen. So the buttonWasClicked: method will be something like this:
- (IBAction)buttonWasClicked:(id)sender {
int size = [usedNumbers count];
if (size > 0) {
int position = (arc4random() % size);
NSNumber *randomNumber = [usedNumbers objectAtIndex:position];
// Do something with your number.
// Finally, remove it from the array:
[usedNumbers removeObjectAtIndex:position];
} else {
// The array is empty.
}
}

Declare Dynamic Array

How can I declare dynamic array? For example:
int k=5;
I want to have an array like below:
int myArray[k];
if i read the question right.. (unlikely at this point)
NSMutableArray *myArray = [[NSMutableArray alloc] initWithCapacity:k];
Sometimes true arrays (not NSArray) are really needed. See for example indexPathWithIndexes:length: in NSIndexPath, it take array of uintegers as parameter. For array allocation you should use the following approach:
NSUInteger *arr = (NSUInteger*)malloc(elementsCount * sizeof(NSUInteger) );
arr[0] = 100;
free(arr);
In Objective-C, the standard way to do this is to use the NSMutableArray class. This is a container that can hold any object (note that int is not an object! You'll have to wrap your integers in NSNumber.) Quick example:
NSMutableArray* someIntegers = [[NSMutableArray alloc] initWithCapacity:1];
[someIntegers addObject:[NSNumber numberWithInt:2]];
//I've added one thing to my array.
[someIntegers addObject:[NSNumber numberWithInt:4]];
//See how I can put more objects in than my capacity allows?
//The array will automatically expand if needed.
//The array now contains 2 (at index 0) and 4 (at index 1)
int secondInteger = [[someIntegers objectAtIndex:1] intValue];
//Retrieving an item. -intValue is needed because I stored it as NSNumber,
//which was necessary, because NSMutableArray holds objects, not primitives.
Well in my book it's ok to use VLAs in Objective-C.
So something like
int foo = 10;
int bar[foo];
is allowed. Of course this is not a dynamic array as in automatically adjusting its size. But if you only need a native array on the stack that's fine.
You can use Objetive-C++.
First rename your class like this: MyClass.mm the ".mm" extension tells Xcode that this clas is a Objetive-C++ class, not a Objetive-C class.
then you can use dynamics C++ arrays like this:
int *pixels = new int[self.view.size.width];
for (int offset = 0; offset = self.view.size.width; offset++) {
pixeles[offset] = rawData[offset];
}
then you can pass "pixels" in a method:
Scan *myScan = [[Scan alloc] initWhithArray:pixels];
the method "initWithScan" is declared like this:
-(id)initWithArray:int[]pixels;
the "initWithScan" implementation is like this:
-(id)initWithScan:int[]pixels {
if (self = [super init]) {
for (int i = 0; i < self.myView.size.width; i++) {
NSLog(#"Pixel: %i", pixels[i];
}
}
return self;
}
I hoppe this was useful.