Is it possible to cast a NSInteger to a NSNumber object?
I need to convert the tag of a UIImageView object to a NSNumber object because I need to pass it as an argument to a function.
You cannot cast it because NSInteger is not an object, just an alias for a built-in type. You can always create a new NSNumber object from NSInteger, like this:
NSNumber *myNum = #(myNsIntValue);
or in the prior version of the compiler, use
NSNumber *myNum = [NSNumber numberWithInteger:myNsIntValue];
since Apple LLVM Compiler 4.0, there is an easier way to create NSNumber object:
NSNumber *x = #1234;
NSNumber *y = #(anIntegerVariable);
This is the more correct answer and it will not produce unexpected error.
NSNumber *myNum = [NSNumber numberWithInteger:myNsIntValue];
Because the doc said:
"numberWithInteger:
Creates and returns an NSNumber object containing a given value, treating it as an NSInteger."
"numberWithInt:
Creates and returns an NSNumber object containing a given value, treating it as a signed int."
Related
My question is as it is in the title. However, if it isn't an object, how can it then be maintained in NSMutableArray as an object? Because NSMutableArray is only for storing objects or am I wrong? :)
Primitive types, like int, must be wrapped in an object before it can be added to a collection class like NSMutableArray. Try this:
int nameOfVariable = 42;
NSMutableArray *array = ... // the initialized array
[array addObject:#(nameOfVariable)];
The last line is modern syntax that essentially means:
[array addObject:[NSNumber numberWithInt:nameOfVariable]];
Later on, when you need to get the value back, you do:
int someVariable = [array[someIndex] intValue];
No, it is not an object and you can therefore not put it in an NSArray. You have to wrap it in an NSNumber, which is an object and can be put in an NSArray.
An int is a primitive type inherited from C (examples of other primitive types are char, long, float, etc.). These are not Objective-C objects. To add a primitive type to an NSMutableArray or any other Objective-C collection, you must wrap them in an object. For number types like int, you would use NSNumber as follows:
int i = 1;
[array addObject:#(i)]; // #(i) is equivalent to [NSNumber numberWithInt:i]
I am trying to grab the value of an NSInteger and set a UILabel value to it. The code is as follows:
counter_.text = [NSString stringWithFormat:#"%#", [counterAmount intValue]];
where counter_ is my label and counterAmount is my NSInteger. I keep getting a "Receiver type 'NSInteger *' (aka 'int *') is not 'id' or interface pointer, consider casting it to id.
I'm not quite sure how to understand this. I appreciate of your help.
intValue is an NSNumber method that returns a C primitive value. %# prints objects. In order to output a C primitive value you have to supply the type in the formatting string. %d is the type for signed integer.
As per the question, and as pointed out to me quite correctly by borrden below, the type being dealt with here is NSInteger rather than NSNumber. In iOS NSInteger is a typedef of int, so you're dealing directly with a primitive type. The NS prefix does not mean that its an object.
Since counterAmount is a NSInteger, you can not use intValue on it (since it isn't an object, you can't send any messages to it, actually).
Instead, use:
counter_.text = [NSString stringWithFormat:#"%d", counterAmount];
Now that being said, if you are displaying this value to a user you should really be using a number formatter so that it is formatted the way that they have set it up to display in the settings app:
NSNumber *number = [NSNumber numberWithInt:counterAmount];
NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.numberStyle = NSNumberFormatterDecimalStyle; // Or whichever style is appropriate for your number.
counter_.text = [formatter stringFromNumber:number];
this is the code:
NSNumber *taskId = [[self.taskList objectAtIndex:indexPath.row] valueForKey:#"identity"];
NSInteger *intTaskId = [[self.taskList objectAtIndex:indexPath.row] valueForKey:#"identity"];
self.taskList is an NSArray which filled with core data fetch request in ViewController's viewDidLoad method.
the taskId is: 1
the intTaskId is: 269303816
In actually, the value stored in core data is: 1
below is my questions:
1, I am confused why the NSInteger incorrect?
2, Should I have to replace NSInteger with NSNumber to avoid any other problems?
NSNumber is an object, whereas NSInteger is simply a typedef for a primitive (non-object) type (like int). NSInteger is not a subclass of NSNumber. Core Data returns numbers as instances of NSNumber. You're getting the weird NSInteger value because it's pointing to an object of type NSNumber but attempting to print it as if it were just an integer.
You'll need to replace NSInteger with NSNumber to avoid any problems. You could also use the intValue method on NSNumber to get back an NSInteger:
NSNumber *objTaskId = [[self.taskList objectAtIndex:indexPath.row] valueForKey:#"identity"];
NSInteger *intTaskId = [objTaskId intValue];
You'll need to do this if you want to do comparisons (greater than, equal too, smaller than) or arithmetic (you can't add an NSNumber to another NSNumber or an NSNumber to a primitive type like an int or float).
How can I solve this problem?
code:
[NSNumber numberWithInteger:[buttonStatsInSection objectAtIndex:row]]
warning: passing argument 1 of 'numberWithInteger:' makes integer from pointer without a cast
Thanks.
numberWithInteger: needs you to give it an int to create the NSNumber. You are giving it an object, because objectAtIndex: returns an object.
Even if the object you have at that row is an NSNumber, or anything else, you still need to get an actual int data type out of it somehow.
For example, if the object you get back is an NSNumber, you could have something like this in the end:
NSNumber * myNSNum = [buttonStatsInSection objectAtIndex:row];
int myInt = [myNSNum intValue];
[NSNumber numberWithInteger:myInt];
Why are you creating a new NSNumber object? Do you really want a copy of it, or do you just want a reference to it? What do you plan to do with it? If you want a copy, you can just do:
NSNumber* copy = (NSNumber*)[[buttonStatsInSection objextAtIndex:row] copy];
Otherwise just do:
NSNumber* num = (NSNumber*)[buttonStatsInSection objextAtIndex:row];
Either way it isn't necessary to go through the process of extracting the int value and the converting it right back to an NSNumber
Is there a way to change the value contained in an NSNumber after it is created without making it point to a different NSNumber?
NSNumber *num = [NSNumber numberWithInt:0];
num = [NSNumber numberWithInt: 1]; // now num points to a different object, which I don't want. I want it the same object still, but different value.
NSNumber is immutable. Actually, it's a subclass of NSValue, and all NSValues are immutable.
No, you can't change the value of NSNumber.
See, for example, this post.