Initialization makes integer without a cast - objective-c

I get this warning and I am not sure how to fix it. The line where I get the warning is
NSInteger thescore = [[myDictionary objectForKey:#"Score"] objectAtIndex:0];
If it makes a difference, myDictionary is a NSDictionary
Edit: How is this? Btw my array is a NSMutableArray and not a NSArray
NSInteger thescore = [[myDictionary valueForKey:#"Score"] integerValue];
Edit 2: #Bavarious mentioned that I should do the following:
int thescore = [[myDictionary objectForKey:#"Score"] integerValue];

The result of call [someArray objectAtIndex:0] is an object. And NSInteger is a primitive type:
typedef long NSInteger;
(cmd + double-click on NSInteger in xcode to see the definition)
I guess you might actually be storing NSNumber objects in your array. In this case, you could do
NSNumber *thescore = [someArray objectAtIndex:0];

Related

-[__NSArrayI floatValue]: unrecognized selector sent to instance

_data = [NSMutableArray new];
NSNumber *value1 = [NSNumber numberWithFloat: 5.0f];
[_data setValue:value1 forKey:#"foothold"];
NSNumber *value2 = [_data valueForKey:#"foothold"];
NSLog(#"a foothold %f ",[value2 floatValue]);//error here
It's strange, but I don't see my error...
You have a few problems.
_data is mistakenly an NSMutableArray instead of an NSMutableDictionary.
Don't use setValue:forKey: and valueForKey: unless you mean to do KVC.
Use modern syntax (it's easier and it avoid issue #2).
Updated code:
_data = [NSMutableDictionary dictionary];
NSNumber *value1 = #5.0;
_data[#"foothold"] = value1;
NSNumber *value2 = _data[#"foothold"];
NSLog(#"a foothold %f ",[value2 floatValue]);
When you get an "unrecognized selector sent to instance" error, you'll be given the name of the method you're attempting to call (in this case floatValue) as well as the type of object you're calling it on (NSArray here).
So in this case, despite value2 being declared as an NSNumber, the value returned from [_data valueForKey:#"foothold"]; is an NSArray, which does not respond to the floatValue selector.
I'm surprised you weren't given other warnings. Given the syntax, it looks like you should be using an NSMutableDictionary rather than an array. In which case, try this:
NSMutableDictionary *_data = [NSMutableDictionary dictionary];
NSNumber *value1 = #5.0f;
_data[#"foothold"] = value1;
NSNumber *value2 = _data[#"foothold"];
NSLog(#"a foothold %f", [value2 floatValue]);

Does iOS coerce NSStrings into NSNumbers?

Subtitle: why does this code work? It seems to allow comparison of NSNumber with NSString types via some sort of coercion. I'm trying to compare a selection from a UISegmentedControl with a previously stored value.
- (IBAction)minSegmentedControlChanged:(id)sender // MINIMUM value
{
UISegmentedControl *s1 = (UISegmentedControl *)sender;
NSMutableArray *pD = [[GameData gameData].curData valueForKey:#"persData"];
// Must make sure max >= min
NSNumber *currMax = [pD objectAtIndex:1];
NSLog(#"%#", [currMax class]); // __NSCFString ?!
int ss1 = s1.selectedSegmentIndex;
NSNumber *SS1 = [NSNumber numberWithInt:ss1 + 2];
if (SS1 >= currMax) SS1 = currMax;
NSLog(#"%#", SS1); // Answer is correct, appears to be an integer
NSLog(#"%#", [SS1 class]); // __NSCFString ?!
[pD replaceObjectAtIndex:0
withObject:SS1];
[[GameData gameData].curData setObject:pD
forKey:#"persData"];
NSLog(#"%#", [[GameData gameData].curData valueForKey:#"persData"]);
}
I am particularly asking about:
NSNumber *currMax = [pD objectAtIndex:1];
NSLog(#"%#", [currMax class]); // __NSCFString ?!
which seems to return a string for a number. [[GameData gameData].curData valueForKey:#"persData"]; is initialized as follows:
_persData = [[NSMutableArray alloc] initWithObjects:#"2", #"8", #"TWL", #"0", #"0", nil];
which is a string at element 1. So why can I ask it for an NSNumber, which reports that it is actually a __NSCFString on which I can do arithmetic comparisons on? I've only been at objective-c for a few months but this seems strange.
Okay, let's walk through this one step at a time.
First of all, all of the elements in _persData are strings. Period. NSString is a class cluster, so the concrete classes of the various instances you inquire about may look weird, but that's to support toll-free bridging and other magic that's not relevant to this discussion.
NSNumber *currMax = [pD objectAtIndex:1];
This line is incorrect. You might think there's some sort of coercion going on, but actually you're just assigning an NSString * to an NSNumber *. Which is wrong, and will explode in your face at the earliest convenience. It so happens that objectAtIndex: returns an id, which is stripped of type information, so the compiler is trusting you to store it in the right kind of pointer, but that's not enforced until you try to send a message to it.
if (SS1 >= currMax) SS1 = currMax;
This is an extremely wily comparison. SS1 is most certainly an NSNumber, but currMax is an NSString. But we're not comparing the values of those objects. To do that, we'd use the compare: method. Instead, we're comparing them as pointers, looking only at their addresses in memory. By some accident of implementation, SS1 seems to always reside at a higher address than currMax.
If all of the foregoing is true, then SS1 is always of type NSString after the above line is executed, which explains why this line:
NSLog(#"%#", [SS1 class]);
Always indicates that SS1 is a string.
You actually initialize the NSMutableArray with NSString, not number.
When you pull object out of NSMutableArray with objectAtIndex, the return type of the function is id, which it will blindly cast to NSNumber, while the actual object is NSString.
It seems that the SS1 >= currMax statement is comparing the addresses of the objects instead of their values.
You can test it out with this snippet of code:
NSNumber *a = [[NSNumber alloc] initWithUnsignedInt: 34];
NSNumber *b = [[NSNumber alloc] initWithUnsignedInt: 3];
NSNumber *c = [[NSNumber alloc] initWithUnsignedInt: 34];
NSNumber *d = [[NSNumber alloc] initWithUnsignedInt: 234];
NSLog(#"%p %p %p %p %d %d", a, b, c, d, a >= b, c >= d);

pointer to integer

I have an array of integer and i'm trying to get an element from the array; xcode keeps showing this message: "initialization makes integer from pointer without a cast"
I know that this warning means that i can't alloc integer to pointer type, and i'm asking how ca i get that element, or if there is a solution to convert pointer to integer
Here is my code:
NSString *pathvalidrep = [[NSBundle mainBundle] pathForResource:#"validrep" ofType:#"plist"];
NSArray *tabreponses = [[NSArray arrayWithContentsOfFile:pathvalidrep] retain];
truerep = tabreponses;
[tabreponses release];
NSUInteger val1 = [truerep objectAtIndex:0]; //the warning apears here
thanx for help :)
Elements of the array are probably NSNumber objects... And the warning is appearing because of this, you assign a pointer to NSNumber to a NSUInteger.
Try :
NSUInteger val1 = [[truerep objectAtIndex:0] integerValue];

Going crazy with UITextField

I'm literally going crazy whit these six rows of code.
NB: nome and prezzo are 2 textFields
NSString *itemName = (NSString *) [rowVals objectForKey:#"name"];
NSString *itemPrice = (NSString *) [rowVals objectForKey:#"price"];
nome.text = itemName;
nome.userInteractionEnabled = YES;
prezzo.text = itemPrice;
prezzo.userInteractionEnabled = YES;
Don't know why when itemPrice is copied in one of those label, the program go in SIGABRT.
Instead if I try to read the content with an NSLog(#"%#",itemPrice); it return the exact value, so it means that is a valid NSString.
The only solution I found is passing through a NSNumber:
NSNumber *itemPrice = (NSNumber *) [rowVals objectForKey:#"price"];
prezzo.text = [[NSString alloc] initWithFormat:#"%#", itemPrice];
There is another way to use directly the NSString?
Probably the value in the #"price" field is NSNumber, and not an NSString. The NSLog method will still provide a correct result, since %# is used for any NSObject subclass, not just NSString.
How about this:
NSString *itemPrice = [[rowVal objectForKey:#"price"] stringValue];
prezzo.text = itemPrice;
The problem might be the object type returned by [rowVals objectForKey:#"price"]. When you place the (NSString *) cast before the method call, you're telling the compiler what type of object is returned, but not actually converting it into an NSString. The line you use below does convert from NSNumber (or whatever other object) to a string: [[NSString alloc] initWithFormat:#"%#", itemPrice]
You might be storing NSNumber's object in NSDictionary instead of NSString.
There could be 2 ways: one would be to convert NSNumber to NSString while adding it to dictionary or the other way would be to convert NSNumber to NSString while assigning it to "itemName".
you may do the conversion for second option like:
NSString *itemPrice = [[rowVals objectForKey:#"price"]stringValue];

How to assign integer from NSMutableArray

I would like to assign NSInteger by using NSMutableArray is there any way to solve this?
It is not working on simulator and cut off when run the application.
NSInteger Section;
NSMutableArray dataSourceSection;
Section = (NSInteger)[dataSourceSection objectAtIndex:2];
Thank you.
A NSMutableArray only stores objects. NSInteger is not an object, but a primitive data type. There is a class NSNumber, however, that can be used instead to store numeric values inside objects. Here's one example.
NSNumber *five = [NSNumber numberWithInteger:5];
NSMutableArray *numbers = [NSMutableArray array];
[numbers addObject:five];
To get the object back and retrieve the integer value use,
NSNumber *firstNumber = [numbers objectAtIndex:0];
NSInteger valueOfFirstNumber = [firstNumber integerValue];
you can't pull an NSInteger out of an NSMutableArray, basically because you can't put anything rather than objects in. in your case NSNumber would be the way to put numbers in NSMutablearray. if you do so you can easily get hold of your object, which is an NSNumber, and convert it to a NSInteger by:
NSMutableArray *array = [[NSMutableArray alloc] init];
// populate the array with NSNumbers
NSInteger number = [[array objectAtIndex:2] intValue];