When to use instance variables instead of properties in objective-C? - objective-c

With the Objective-C's #property directive I can declare properties for which getter and setter methods will be created automatically. I can't think of any particular reason to use instance variables where I would have to write my own setter and getters, but I'm sure there must be an example where using instance variables is more preferable. Could there be any reason to use instance variables instead of properties? Are there any practical examples for it?

The problem is on this line
slope = (line_cordinates[3] - line_cordinates[1]) / (line_cordinates[2] - line_cordinates[0]);
slope is declared a float, but line_cordinates is an array of int.
So you are doing all of the math on the right hand side as int math, then assigning it to a float. So the final result of all the int operations is implicitly converted to float, but by then you have already lost the precision from truncation, etc.
The quickest fix would be to simply declare
float line_cordinates[4] = {0.0, 0.0, 0.0, 0.0};

Use,
slope = static_cast<float>((line_cordinates[3] - line_cordinates[1])) / (line_cordinates[2] - line_cordinates[0]);
You need to typecast any of the operand on right hand side to float. So expression will result in float.
int op int = int
float op int = float

Related

Parse Number Column to CGFloat

The issue I am having is that I'm using an image height stored in a Parse class column with a type of Number. I'm then taking that height number and using it to set the UITableview row height. The problem is that when I try to use the number column value, it returns an error saying the types don't match. I'm doing this in Objective C. How can I use the Number value for the row height? I'm pretty sure I need to convert the Number value to a CGFloat but I'm not sure.
NSNumber has already provided options for you to do it.
I suggestion you read on the documentation found here.
excerpt from Apple doc:
NSNumber is a subclass of NSValue that offers a value as any C scalar (numeric) type. It defines a set of methods specifically for setting and accessing the value as a signed or unsigned char, short int, int, long int, long long int, float, or double or as a BOOL.
to answer your question.
you can use the floatValue to get a CGFloat from an NSNumber
example:
CGFloat myFloat = [number floatValue];

Objective-C API: Can an NSNumber become an Int in Swift?

I am writing a framework in Objective-C, and the goal is it should be a joy to use in Swift as well.
One of my properties is a nullable NSNumber. Is there any way to bridge this to an optional Int when the API is used in Swift?
As per the documentation:
Swift automatically bridges certain native number types, such as Int
and Float, to NSNumber.
It also allows you to pass a value of type Int, for example, to an
argument expecting an NSNumber. Note that because NSNumber can contain
a variety of different types, you cannot pass it to something
expecting an Int value.
All of the following types are automatically bridged to NSNumber:
Int
UInt
Float
Double
Bool
So you can safely use these scalar types in swift and cast them to NSNumber in objc, but not the other way around. NSNumber may represent a float value, and you will see an error if you cast it to Int in swift.

What is int foo[] = {1200,100} and how do I recreate it in Swift?

Testing out some third party objective-C code I see the following:
int beepData[] = {1200,100};
What am I looking at here? An int is being created from a pair of other integers? I've not seen this feature before.
I would also like to know how to create the same variable in Swift.
EDIT
I assumed this was returning an int, not an array. The code I'm reviewing looks like this:
int beepData[] = {1200,100};
[[DTDevices sharedDevice] barcodeSetScanBeep:TRUE volume:10 beepData:beepData length:sizeof(beepData) error:nil];
Where the method signature I am intending to pass the variable to is:
-(BOOL)barcodeSetScanBeep:(BOOL)enabled volume:(int)volume beepData:(int *)data length:(int)length error:(NSError **)error;
I guess the right question might have been - what is (int *) and how might I create one in Swift?
What am I looking at here?
That is an array of ints, with two elements.
[How can I] create the same variable in Swift?
The same variable in swift might be declared as:
var beepData : [Int] = [ 1200, 100 ]
You might find this answer about different ways to declare an array in C useful
What is (int *)
It's an int pointer, it points to the memory address of an int. Incrementing it would move along the memory addresses (in int-sized chunks) and point to the next bit of memory.
[1][3][5][4][2]
^
This little arrow represents an int*. Even though it currently points to 1,
incrementing it doesn't equal 2. In this case it would equal 3, the value of the int in the next block of memory.
[1][3][5][4][2]
^
How might I create one in Swift?
To be quite honest, I'm not sure if Swift has pointers in the normal sense. I've not used it a great deal. However, if you are porting that method, I'd probably give it an array of ints.
func barcodeSetScanBeep(enabled : Bool, volume : Int, beepData: [Int], length : Int, error : NSError)
That's a C array, declared with 1200 and 100 as the members of the array.
Its declared with the type, and a bracket with the size (or empty for compiler deduced size), such as int cArrayOfInts[] = blahblahblah.
Note how the members of the array can be primitives, instead of objects. This isn't possible in Objective-C.
To recreate this in swift, simply use var beepData = [1200, 100] and it will be type inferred to an array of Ints.
James already answered the particulars of your question - consider this some additional information.
Declarations in C are based on the types of expressions, not objects. If you have an array of integers and you want to access the i'th integer, you would write
x = arr[i];
The type of the expression arr[i] is int, so the declaration of arr is written as
int arr[N]; // arr is an N-element array of int
Similar logic applies to pointer declarations; if you have a pointer to a double and you want to access the pointed-to value, you'd write
y = *p;
The type of the expression *p is double, so the declaration of p is written as
double *p;
Same for function declarations; you call a function that returns an integer as
x = f();
The type of the expression f() is int, so the declaration of the function is written as
int f( void ); // void means the function takes no parameters
C declaration syntax uses something called a declarator to specify an object's array-ness, pointer-ness, or function-ness. For example:
int x, arr[10], *p, f(void);
declares x as a plain int, arr as a 10-element array of int, p as a pointer to an int, and f as function taking no parameters and returning int.
You'll occasionally see pointer declarations written as T* p, however they will be parsed as T (*p); the * is always part of the declarator, not the type specifier.
C declaration syntax allows you to create some pretty complex types in a compact format, such as
int *(*(*f[N])(void))[M];
In this declaration, f is an N-element array of pointers to functions returning pointers to M-element arrays of pointers to int.
In your declaration
int beepData[] = {1200, 100};
beepData is being declared as an array of an unknown size; the size is taken from the number of elements in the initializer {1200, 100}, in this case 2.
I know nothing about Swift, so I wouldn't know how to translate the C code to it. The best I can do is explain how the C code works.

Do NSDouble, NSFloat, or other types than NSInteger exist?

Over at In Cocoa do you prefer NSInteger or just regular int, and why?, there was mention of NSDouble and NSFloat, but I can't see a reference for those in any documentation. If NSInteger's purpose is for architectural safety, what about other types such as double or float?
NSInteger exists because the int type varies in size between 32-bit and 64-bit systems. float and double don't vary in size the same way, so there's no need to have wrapper types for them.
There is no NSFloat but I know the Core Graphics API eventually changed from float to CGFloat so that it could use a double on some architectures.
It is best to use the exact types that API headers declare. This makes type changes automatic if you ever recompile your code for a different target.
It's also about conventions.
A typedef to an int is incompatible to int int itself.
Example: pid_t is of type int, but passing an int would create a warning.
Why? Because you want to be sure that if you cross API boundaries everyone knows what the code expects.
There are float and double types, i.e NSTimeInterval. It's not really about the underlying type, but the convention to adhere to.
If you declare a local int as a loop counter and you do not plan to pass it to a well-defined API, it's fine to call an int an int.

float in an object's message

I have an object with a method that should take a float as a parameter, but the value in the object is not correct. Passing an int or double fixes the problem, but why doesn't float work?
Because you haven't provided a prototype for the method in the scope of the caller.