Why can you declare an NSInteger with a string value? - objective-c

Why is it that you can do something like this?
NSInteger something = #"something";
It feels weird that this doesn't throw an error and instead returns some number that, in fact, is an NSInteger.

For me it says Incompatible pointer to integer conversion initializing 'NSInteger' (aka 'int') with an expression of type 'NSString *'
I feel, what you get number is memory address of that NSString.

In Languages Like Objective C, When You Define a class or a constant string(What you define like #"something" is a constant string), it will be stored somewhere and the pointer to it will be used. Pointers are 32-bit and 64-bit. 32-bit pointers are 32-bit Integers so they can easily be casted to an integer. So there is no way to throw an error as it is a legal assignment.

it's the same line of code
NSInteger something = [#"something" integerValue];

Related

improper setting variable in objectiveC

I'm facing issue that xcode showing me warning: Incompatible pointer to integer conversion sending 'id _Nullable' to parameter of type 'unsigned long long'
the line is:
NSDecimalNumber *amount_total = [NSDecimalNumber decimalNumberWithMantissa:indic[#"amount"] exponent:-2 isNegative:NO];
it complain of indic[#"amount"] and this is a value of amount came from React-Native. even if I console log this in xcode it showing me a number which is came right from RN.
any solution to avoid that, however the app also crash because of this.
Thanks
Foundation collections (including NSDictionary) store numbers as NSNumber objects. The error is informing you that it is expecting an unsigned long long, so you should use unsignedLongLongValue to extract that value from the NSNumber in your NSDictionary:
NSDecimalNumber *amount_total = [NSDecimalNumber decimalNumberWithMantissa:[indic[#"amount"] unsignedLongLongValue] exponent:-2 isNegative:NO];
See Most Collections Are Objects and Numbers Are Represented by Instances of the NSNumber Class.

How to remove 100s of warnings "implicit conversion loses integer precision: 'NSInteger' (aka 'long') to 'int'" I got after updating to arm64?

Problem:
Yesterday I converted a large project of mine to support arm64 and after that I got 500+ warnings at once. About 70% of them are where NSInteger is being assigned to int or vice versa, and remaining are where NSUInteger is formatted in NSString like this:
NSInteger a = 123;
NSString *str = [NSString stringWithFormat:#"Int:%d", a]; //warning: value of 'NSInteger' should not be used as formate argument; add an explicit cast to 'unsigned long' instead.
Now I do know how to adress them manually, but that's a huge task and very laborious.
I'm also aware that I can silence the type mismatch warnings all together, but I don't want to do that. Of course, they're very helpful.
What I've tried:
I've converted [NSNumber numberWithInt:abc]; to [NSNumber numberWithInt:(int)abc]; using find-n-replace. It fixed some.
I've also tried to change all my int properties to NSInteger properties
but it doubled the number of warnings (reached to 900+ count). So I
reverted.
I've also tried to find some regular expression but couldn't find
something suitable to my needs.
Question:
I'm looking for a regular expression or any other workaround somebody has tried which can reduce the amount of work needed to fix them manually.
Thanks in advance.
NSInteger a = 123;
NSString *str = [NSString stringWithFormat:#"Int:%ld", (long)a];
After updating to 64 bit need to do typecast like this((long)a). %d is only for 32 bit range %ld for long integer. For better understanding got through this apple documentation.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Cocoa64BitGuide/ConvertingExistingApp/ConvertingExistingApp.html
In case someone else's facing a similar situation, I want to clarify how to deal with it. Although #Raju's answer is suggesting to do it manually (which I wanted to avoid), I found exactly what I needed at the link he shared.
Apple has provided a script for 64bit conversion called ConvertCocoa64, located at/Developer/Extras/64BitConversion/ConvertCocoa64 which not only converts all int to NSInteger it also deals with float to CGFloat conversion, as stated:
It converts most instances of int and unsigned int to NSInteger and
NSUInteger, respectively. It doesn't convert ints in bit-field
declarations and other inappropriate cases. During processing, the
script refers to a hardcoded list of exceptions.
In addition to above conversions it also flags the lines in code which need manual fix. So this might help with the warnings of String Formats.
Please refer to this link for complete details. It not only explains how to use the script but also suggests some very important post 64-bit migration check points.
objective c implicit conversion loses integer precision 'NSUInteger' (aka 'unsigned long') to 'int
Change key in Project > Build Setting "implicit conversion to 32Bits Type > Debug > *64 architecture : No"
Other warning
Change key in Project > Build Setting "typecheck calls to printf/scanf : NO"
Explanation : [How it works]
Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified, and that the conversions specified in the format string make sense.
Hope it work
[caution: It may void other warning of 64 Bits architecture conversion].

implicit conversion loses integer precision 'long' to 'int'

I have a problem getting this problem fixed on xcode don't no why it happens it says
implicit conversion loses integer precision 'long' to 'int'
[self newScheduleNotification:[ud objectForKey:dateKey] addNotifKey:[sw tag] ];
This warning appears, if you assign a integer value (L-value) of type long to a variable (R-Value) of type int. This includes passing arguments of type long to parameters of type int. Probably you do that at [sw tag].
"Integer precision lost" means that the long expression delivering the value might have a value that cannot be represented by the int destination.
Change your type for notifKey to NSInteger in newScheduleNotification:addNotifKey:. You're passing it an NSInteger, which is a long on 64-bit, and an int on 32-bit, but your method is asking for an int. Using NSInteger in both places will handle the type for you. You must be on a 64-bit simulator or device. If you ran on a 32-bit sim or device you'll see the warning goes away because then you're passing an int to a method looking for an int.

Set value of a int from an NSarray

how can I set an int to a value from array ?
I try like that:
int counter;
counter = signArr[4];
doesn't work, I get an err " incompatible pointer to integer conversion sending 'int' to parameter of type 'id' "
thank for help :)
From your comment we can guess that the number is boxed in an NSNumber instance. We can test with a log statement (or in the debugger):
NSLog(#"The class is %#", NSStringFromClass[signArr[4] class]));
and then, if it is an NSNumber instance, looking at the methods on offer we can see integerValue which will provide what you're looking for.
The error you saw
incompatible pointer to integer conversion sending 'int' to parameter of type 'id'
tells you that you want an int but that you have an id. You should know that id is the generic pointer type used in ObjC (if you don't you need to go and read the documentation some more) and thus you need to find a way to convert from the object pointer to the primitive int. The first step is finding out what the object class type is and then checking the docs to see what it offers you to help achieve your goal.

How to convert an pointer to become a object?

I using something like this : [tmpArray insertObject:something[i] atIndex:i];
But I got a MSG : passing argument 1 of "insertObject:atIndex:" makes pointer from integer without a cast.
What should I do to fix it?
I guess your something[] array is a C array of int, if this is the case you cannot pass its value at that position into an NSArray since it contains objects (and objects in obj-C are referenced by pointers).
What you could do is wrap the int into a NSNumber this way:
[tmpArray insertObject:[NSNumber numberWithInt:something[i]] atIndex:i];
You can't magically make random pointer into an object, you need to understand what the type of the pointer is and do something semantically reasonable with that type. Also, that is not what the error you are seeing is about. The error is because the type expected is a pointer (and an object in ObjC is also a pointer type), and the type info of the thing you are passing is a scalar.
Taking a wild guess, something is probably an array of ints, if so what you want to do is wrap is the integer in an NSNumber in order to store it in a collection:
//assuming this:
int something[100];
//then your line should be this:
[tmpArray insertObject:[NSNumber numberWithInt:something[i]] atIndex:i];
Obviously you will need to unbox the value anywhere you access it. If it is not an array of integers then you will need to do something else (though probably similiar), but without more info I can't tell you exactly what.