get multiple output from a single method in Objective-c - objective-c

I have my own class and am writing a method with multiple input (three float values) and multiple output (three float values). I don't figure out how I can get multiple output from a single method. Any ideas?
My current method looks like this:
- (void)convertABC2XYZA:(float)a
B:(float)b
C:(float)c
outputX:(float)x
outputY:(float)y
outputZ:(float)z
{
x = 3*a + b;
y = 2*b;
z = a*b + 4*c;
}

One way to “return” multiple outputs is to pass pointers as arguments. Define your method like this:
- (void)convertA:(float)a B:(float)b C:(float) intoX:(float *)xOut Y:(float *)yOut Z:(float)zOut {
*xOut = 3*a + b;
*yOut = 2*b;
*zOut = a*b + 4*c;
}
and call it like this:
float x, y, z;
[self convertA:a B:b C:c intoX:&x Y:&y Z:&z];
Another way is to create a struct and return it:
struct XYZ {
float x, y, z;
};
- (struct XYZ)xyzWithA:(float)a B:(float)b C:(float)c {
struct XYZ xyz;
xyz.x = 3*a + b;
xyz.y = 2*b;
xyz.z = a*b + 4*c;
return xyz;
}
Call it like this:
struct XYZ output = [self xyzWithA:a B:b C:c];

Methods in Objective-C (unlike, say, Python or JavaScript) can only return at most 1 thing. Create a "thing" to contain the 3 floats you want to return, and return one of those instead.
Instead of returning, you can use output parameters.

This is more related to C than objective-c.
You need to pass the values by references. Your function should be declared like this:
- (void)convertABC2XYZA:(float)a
B:(float)b
C:(float)c
outputX:(float *)x
outputY:(float *)y
outputZ:(float *)z;
and called like this:
[receiver convertABC2XYZA:a B:b C:c outputX:&x outputY:&y outputZ:&z];

Related

Swift let computed property to Objective C syntax

I have this code in a Swift application and was curious of what its equivalent syntax would be in Objective C
typealias Signal = (Float) -> (Float)
static let sine: Signal = { (time: Float) -> Float in
return amplitude * sin(2.0 * Float.pi * frequency * time)
}
I believe I would declare Signal as follows:
typedef float (^Signal)(float);
but I am not sure how I would setup a similar way of setting up the syntax to retrieve the value. I thought about a class method but the didn't quite work out.
Thank you
This is not a computed property. This is a “closure”.
So this defines a type alias for a closure that takes a Float as a parameter and returns a Float:
typealias Signal = (Float) -> (Float)
You can create an instance of this Signal closure like so:
let doubler: Signal = { $0 * 2 }
And you can call that closure like so:
print(doubler(21)) // 42
The equivalent Objective-C syntax to define the type for a “block”:
typedef float (^Signal)(float);
To create an instance of a Signal block:
Signal doubler = ^(float input) {
return input * 2;
};
And to call it:
NSLog(#"%f", doubler(21)); // 42

Issue with scope of variables in C, why a function prints what it's supposed to print

What exactly is going on in this program here? Why does myFunction print 3 for x?
int myFunction(int);
void main(void) /* local variables: x, result in main */
{
int result, x = 2;
result = myFunction(x);
printf("%i", result); /* prints "3" */
printf("%i", x); /* prints "2" */
}
int myFunction (int x)
{
x = x + 1;
printf("%i\n", x); /* prints "3" */
return x;
}
That's because the parameter is a local variable in the function.
When the function is called, there is space allocated on the stack for the parameter, and the value from the variable x is copied into the parameter.
In the function the parameter x is a local varible, separate from the variable x in the calling code. When x is increased in the function, that only happens to the local copy.
When the function ends, the parameter goes away when the stack frame for the function is removed from the stack.
You should read about the differences between pass by value vs. pass by reference in function variables (see here).
In your case, you are passing x by value to myFunction, the function basically gets the value of x (2) and increments it, but never changes the original value of x from your main function.

Why can't you assign and call a block at the same time?

The following code compiles:
^{}();
And this compiles:
void (^x)();
(x = ^{})();
But this doesn't:
(void (^x)() = ^{})();
The error I get is Expected ')'. Is this a bug with llvm or something? It's totally holding me back from pretending Objective-C is JavaScript.
This wouldn't make sense in a C-like language. To see why, let's build the statement from the ground up.
First, we'll use your working declaration for x:
void (^x)();
Now let's initialize it in the same statement:
void (^x)() = ^{};
So far so good - x has been initialized with the correct block. So let's invoke x now. But where will the () go? Naturally, we need to place the () immediately after a block-valued expression. However, in C, declarations are statements, not expressions so
(void (^x)() = ^{})();
doesn't make sense. The only place the () can go is after the ^{}:
void (^x)() = ^{}();
But ^{}() has type void, not type void (^)().
To sum up: you can't declare a block variable and invoke it at the same time. you'll have to either declare and initialize the variable, and then call it
void (^x)() = ^{};
x();
or declare it and then assign and call it
void (^x)();
(x = ^{})();
or just separate all three:
void (^x)();
x = ^{};
x();
As a concluding thought, let's say it was desirable to declare and invoke blocks at the same time. If we decided to allow code like (void (^x)() = ^{})();, then for the sake of consistency, we would have to also allow code such as ++(void x = 4); or (void x = 1) + (void y = 2);. I hope you'll agree that these just look strange in C.
As an analogy, consider:
This compiles:
if (42) { }
And this compiles:
int x;
if (x = 42) { }
But this doesn't:
if (int x = 42) { }

Objective C equivalent of C method signature

I want make a function to include in my code to calculate percentages.
In Php, it's :
function percent(a,b){
return a/b*100;
}
In Objective C, I don't know. I tried:
-(void)percent(a,b){
return a/b*100;
}
But there are 2 errors. Could you me explain how to make it work?
Thank you for you help
A method is defined in a slightly different syntax than you're used to:
- (float)percentWithA:(float)a dividedByB:(float)b
{
return a / b * 100;
}
The parameters are "strewn" throughout the method call. For instance, this method's name would be percentWithA:dividedByB:. You don't need to be as explicit as this call, however. For example, you could do this:
- (float)percent:(float)a :(float)b { /* ... */ }
But it doesn't provide much context.
The more correct way to do this will be:
- (float)precentageByDevidingFloat:(float)a byFloat:(float)b {
float returnValue = 0;
if (b != 0)
returnValue = a / b * 100;
return returnValue;
}
This way you use a more correct naming convention , you actually return a float and your safe in case some one gave you the value 0 in B.
(which should be covered by documentation)
You could also do it like this, with a C function:
// in your .h
float percent(float a, float b);
// in your .m or .c
float percent(float a, float b)
{
return a / b * 100.0f;
}
Or, if you are into macros:
// remember to always enclose macros in parentheses
#define percent(a, b) (a / b * 100.0f)
And you would call it like this:
percent(50, 20);
Objective-C uses a strange convention of having parameter names as part of a method name and therefore parameter declarations are embedded in a method name.
-(float)percentOf:(float)a over:(float)b
{
return (a/b) * 100.0;
}
The first type in parentheses defines the return type, the parameters come after colons and also have their type in parentheses.

function with multiple arguments

how to pass multiple arguments in a single function in Objective-C? I want to pass 2 integer values and the return value is also integer. I want to use the new Objective-C syntax, not the old C/C++ syntax.
In objective-c it is really super easy. Here is the way you would do it in C:
int functName(int arg1, int arg2)
{
// Do something crazy!
return someInt;
}
This still works in objective-c because of it's compatibility with C, but the objective-c way to do it is:
// Somewhere in your method declarations:
- (int)methodName:(int)arg1 withArg2:(int)arg2
{
// Do something crazy!
return someInt;
}
// To pass those arguments to the method in your program somewhere:
[objectWithOurMethod methodName:int1 withArg2:int2];
Best of luck!
Since this is still google-able and there are better solutions than the accepted answer; there's no need for the hideous withArg2 – just use colons:
Declaration:
#interface
-(void) setValues: (int)v1 : (int)v2;
Definition:
#implementation
-(void) setValues: (int)v1 : (int)v2 {
//do something with v1 and v2
}
Like this:
int sum(int a, int b) {
return a + b;
}
Called like this:
int result;
result = sum(3, 5);
// result is now 8
More here
int add (int a, int b)
{
int c;
c = a + b;
return c;
}
link text