Handle NSNumber and NSInteger - ios

Following is a code snippet i am using to add data to nsmutable array, now I am not sure on what to type cast it on while extracting, i need integer value.
Problem is that I am getting warnings of 'id' and 'NSInteger' conversion. What could be better way of extracting:
self.itemsBottom = [NSMutableArray array];
for (int i = 20; i < 30; i++)
{
[itemsBottom addObject:#(i)];
}
wanna do something like:
NSInteger itemAddressed = [self.itemsBottom objectAtIndex:itemIndex]

In this statement
[itemsBottom addObject:#(i)];
you are boxing the integer value to NSNumber.
While here
NSInteger itemAddressed = [self.itemsBottom objectAtIndex:itemIndex]
you are tried to store NSNumber to NSInteger, hence getting the error.
You can use :
NSInteger itemAddressed = [[self.itemsBottom objectAtIndex:itemIndex] integerValue];
Or in short :
NSInteger itemAddressed = [self.itemsBottom[itemIndex] integerValue];

All seems reasonable...I would think the last line would need to be...
NSInteger itemAddressed = [self.itemsBottom[itemIndex] integerValue];
Maybe?

Related

Array items showing error in IOS

I have an array with some items to rotate the image view when button is clicked, now when I pass the array with getting current index it showing an error, I'm confused why I'm getting this.
My code is this:
- (IBAction)my:(id)sender {
NSString *cureentIndex=0;
NSArray *persons = [NSArray arrayWithObjects:#"M_PI",#" M_PI_4",#" M_PI_2",#"M_PI*2", nil];
NSArray *person = #[#"M_PI", #"M_PI_4", #"M_PI_2"];
_imageView.transform = CGAffineTransformMakeRotation(person[cureentIndex])
if currentIndex != persons.count-1 {
currentIndex = currentIndex + 1
}else {
// reset the current index back to zero
currentIndex = 0
}
}
The error is here:
You have declared cureentIndex as NSString *, so when you say person[cureentIndex] the compiler thinks that person must be a dictionary, since you are using the [] access with an object. This causes the error since person is actually an array and it cannot be indexed with a string.
I think you meant to declare cureentIndex as int, or perhaps you meant to say currentIndex?
There are a lot of issues, please try this
NSInteger currentIndex = 0;
NSArray<NSNumber *> *persons = #[#(M_PI), #(M_PI_4), #(M_PI_2)];
- (IBAction)my:(id)sender {
_imageView.transform = CGAffineTransformMakeRotation(persons[currentIndex].doubleValue)
currentIndex = (currentIndex + 1) % persons.count;
}
There are some errors:
The index must be an int
NSString *cureentIndex=0;
becomes
int currentIndex = 0;
and the array must be of double not string, CGAffineTransformMakeRotation requires a CGFloat that is a double
NSArray *person = #[#"M_PI", #"M_PI_4", #"M_PI_2"];
becomes
NSArray *person = #[[NSNumber numberWithDouble:M_PI], [NSNumber numberWithDouble:M_PI_4], [NSNumber numberWithDouble:M_PI_2]];
and
_imageView.transform = CGAffineTransformMakeRotation(person[cureentIndex])
becomes
_imageView.transform = CGAffineTransformMakeRotation([person[cureentIndex] doubleValue]);
I don't know why you set currentIndex's property to NSString, In fact we always set the XXXindex(current/last/next) to int or NSInteger property.
Another, the person is an array, it's key must be an int!, it's
value could be any object.
I fix your code to this:
NSInteger currentIndex = 0;
NSArray *person = #[#"M_PI", #"M_PI_4", #"M_PI_2"];
CGFloat rotate = [person[currentIndex] floatValue];
_imageView.transform = CGAffineTransformMakeRotation(rotate);
you will find it did't work well, the ratate will be 0! Because, the NSString's method floatValue or doubleValue can only change string(like: #"123" #"0.5") to a number, the string(like: #"M_PI") can't be change to a right number.
I fix your code to this again:
NSInteger currentIndex = 0;
CGFloat mPi = M_PI;
NSArray *person = #[#(mPi), #(mPi / 4.0), #(mPi / 2.0)];
CGFloat rotate = [person[currentIndex] floatValue];
_imageView.transform = CGAffineTransformMakeRotation(rotate);
The Code works well! This is because M_PI is A Macro, if you
write code #"M_PI", the system can't recognize its value 3.1415926. So
your must write M_PI instead of #"M_PI".
In fact, this problem's core is you need a number, so your array must include some numbers! Or some string just like number! :)

How to get last array object as int

How can I get the last object from an array as an int, for example if I have 20 objects in the array, how can I get the last object as an int variable that = 20. Or if the array had 999 objects, the last object int would = 999.
How can I do this? I have tried using (int)array.lastobject but have had no luck, any help would be greatly appreciated.
It depends on what type of objects are being stored in the array? if they are NSNumber or NSString than you can do this:
int myVar = [[array lastObject] intValue];
Edit:
Your question is rather confusing it also seems that you want array count instead of last object? If thats the case than use this:
int myVar = [array count];
Option 1
int yourVariable = [[yourArray lastObject] intValue];
Option 2
int yourVariable = [[yourArray objectAtIndex:([yourArray count]-1)] intValue];
you can use lastObject method to get last object from array
int lastValue = [[yourArray lastObject] intValue];

How to return an NSNumber converted to NSInteger

With NSNumber being a class, I am trying to convert it to an NSInteger to do some computations. In NSLog, it shows that I am converting and doing the multiplication correct. However, when I got to return doubler as a regular NSInteger, I get "Implicit conversion of 'NSInteger' (aka 'long') to 'NSNumber* ' is disallowed with ARC". Where am I going wrong and what do I do to make this correct?
- (NSNumber *) numberThatIsTwiceAsBigAsNumber:(NSNumber *)number {
NSInteger doubler = [number integerValue] * 2;
NSLog(#"%ld", (long)doubler);
return doubler;
}
EDIT: For those curious, this is how I solved it:
NSInteger unboxing = [number integerValue] * 2;
NSNumber *boxing = [NSNumber numberWithInteger:unboxing];
return boxing;
You need to return the number as NSNumber, not NSInteger. So, convert the NSInteger to NSNumber before returning.
return #(doubler);
Change your return type to
- (NSInteger)
If you intend to continue to use it as such, or explicitly cast it.

Loading NSMutableArray objects into an IBCollection of Labels

My problem is that when I use fast enumeration to load objects from my array, like so:
for(SetOfObjects *set in _myArray){
NSLog (#"%#"[set anObject];
}
It will print out my specified object without a problem, however when it comes time to assign these objects to an NSArray of labels. The last object returns as 0.
Like so:
for(SetOfObjects *set in _myArray){
for(UILabel *label in _arrayOfLabels){
int i = [set intObject];
NSString *string = [NSString stringWithFormat:#"%i",i];
label.text = string;
}
}
I think, I have gone wrong here. The code works, but the problem is that all labels are then set as 0.
Any tips welcome.
You are iterating the labels within each SetOfObjects instance, when in fact you want to iterate both arrays at the same time, which cannot be done using fast enumeration.
Instead revert to indexed-access of both arrays:
NSInteger count = [_myArray count];
NSAssert([_arrayOfLabels count] == count, #"Different array sizes!");
for (NSInteger index = 0; index < count; index++) {
SetOfObjects *set = _myArray[index];
UILabel *label = _arrayOfLabels[index];
int i = [set intObject];
NSString *string = [NSString stringWithFormat:#"%i",i];
label.text = string;
}
Note the assertion to check that both arrays are the same size.
EDIT: Oops, i was a bad variable name to choose for the index...

NSMutableArray with int values from 1 to 100

This should be dead easy, but somehow it doesn't want to work for me. Using iOS 7 and XCode 5.
All I'm trying to do is create an array with values from 1 to 100.
NSMutableArray *array;
for (int i = 0; i < 100; i++)
{
[array addObject:i];
}
This doesn't work. I get a "Implicit conversion of 'int' to 'id' is disallowed with ARC.
I get it, I can't add primitive types to an NSMutableArray.
[array addObject:#i];
This doesn't work either. I get a "unexpected '#' in program"
[array addObject:[NSNumber numberWithInt:i]];
[array addObject:[NSNumber numberWithInteger:i]];
(either case) This "works" (compiles) but it really doesn't "work". The problem with this is that the value from NSNumber is really not a 1-100. What I get for each row is "147212864", 147212832", "147212840"...not what I want.
Lastly:
for (NSNumber *i = 0; i < [NSNumber numberWithInteger:100]; i++)
{
[array addObject:i];
}
This also doesn't compile. I get an error on the i++. "Arithmetic on pointer to interface 'NSNumber', which is not a constant size for this architecture and platform"
Any suggestions on how to do this extremely simple thing on obj-c?
Either one of these should work:
NSMutableArray *array = [NSMutableArray array];
for (int i = 0; i < 100; i++) {
[array addObject:#(i)];
}
or
NSMutableArray *array = [NSMutableArray array];
for (int i = 0; i < 100; i++) {
[array addObject:[NSNumber numberWithInt:i]];
}
Here are the reasons why your code snippets did not work:
[array addObject:i] - You cannot add primitives to Cocoa collections
[array addObject:#i] - You forgot to enclose the expression i in parentheses
NSNumber *i = 0; i < [NSNumber numberWithInteger:100]; i++ - You cannot increment NSNumber without "unwrapping" its value first.
If memory serves, I think you're simply missing parenthesis around the NSNumber shorthand expression.
NSMutableArray *array = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < 100; i++)
{
[array addObject:#(i)];
}
Minimally, #i should be #(i) as described here. You are also forgetting to allocate and initialise your array
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i = 0; i < 100; i++) {
[array addObject:#(i)];
}
And since you are getting: "147212864", 147212832", "147212840"...not what I want., I think you are probably printing out your information wrongly or because the array is unallocated, that's simply garbage. Can you show us how you are outputting?
NSMutableArray *array = [[NSMutableArray alloc] init];
NSNumber *myNum;
for (int i = 0; i < 100; i++) {
myNum = [[NSNumber alloc]initWithInt:i];
[array addObject:myNum];
}
NSLog(#"%#", array); // 1 - 99 as expected
Worked for me :)
Just saying: Turn on all reasonable warnings in your Xcode project. Then read what the warnings are saying and do something about them. When you write something like
for (NSNumber *i = 0; i < [NSNumber numberWithInteger:100]; i++)
What does a for loop do? An object is in the end a pointer. So you initalise i to nil. Then you compare a pointer with a random pointer: [NSNumber numberWithInteger:100] returns a pointer to an object which could be anywhere in memory, and you compare pointers. Next the i++: No, you can't increment a pointer to an NSNumber. It doesn't make sense.

Resources