How do I return CGpoint function? - objective-c

If i have this function:
-(CGPoint)limitPosition:(CGPoint)position {
//code here
return position;
}
how do I return it to a variable?
This:
CGPoint a;
CGPoint b;
a = [self limitPosition: b];
Doesnt work.

Without a clearer description of what you mean by "doesn't work", and probably what's going on where you have //code here, it's hard to say.
Basically, you can pass a CGPoint to and from a function or method with the syntax as you have it. It'll be passed by value, so that any changes to position inside the function will not be reflected in the variable passed as argument (b), but should be copied back in the return value (to a).
In the code fragment shown, you don't initialise a or b, so they may contain garbage. And obviously the method body isn't doing much. But otherwise it looks kosher, so the problem is probably elsewhere.

Related

How to I return a structure from an objective-C method?

I am writing code for the iPad. I have a point structure that I define:
typedef struct __Point32_t
{
int32_t x;
int32_t y;
}Point32_t;
Here is my code to receive a structure back from an objective-C method:
Point32_t ModalityPan = [self ReadPoint];
Here is the method:
-(Point32_t)ReadPoint
{
Point32_t P;
P.x = [self ReadInt];
P.y = [self ReadInt];
return P;
}
The assignment of the return value to the structure creates an error at compile time. The error claims I have an invalid initializer. If I change the assignment to:
Point32_t * ModalityPan = [self ReadPoint];
the error goes away. So I am left wondering what is actually being passed back in Objective-C. I have searched through many posts, some here at SO, and I am under the impression that structures are passed and returned to and from methods in Obj-C without needing to reference the structure (e.g., I am allowed to pass by value).
Can anyone explain what is happening under the hood here? What is coming back, a reference or a structure? and if a structure, why do i need to specify a reference as the type of variable being assigned to?
Well it turns out that the compiler was warning me in a very indirect way that my method was not defined in the #interface and the implementation for the method was below my using it. So the compiler appears to not have been able to figure out what the return type was. It compiles correctly now.

Variable Scope in Objective-C

I'm getting started with Objective-C, and there is something about variables scope that I still didn't get. I searched about it, but I still couldn't catch what I'm doing wrong.
I'm trying to create a code that will give me the x,y difference between two point. The first NSLog inside the first IF shows the right value for pointWhereDragBegan.x and .y, but when I try to get the value of the pointWhereDragBegan in the second IF statement, the value I get for pointWhereDragBegan.x is -1.998683 and .y is 0.0.
I'm sure it is something really simple, I just can't catch my mistake.
- (void)drag:(UILongPressGestureRecognizer *)drag{
CGPoint pointWhereDragBegan;
if(drag.state == UIGestureRecognizerStateBegan){
pointWhereDragBegan = [drag locationInView:self];
NSLog(#"Drag started at %f,%f",pointWhereDragBegan.x,pointWhereDragBegan.y);
}
if(drag.state == UIGestureRecognizerStateEnded){
CGPoint pointWhereDragEnded = [drag locationInView:self];
float xDragged = pointWhereDragEnded.x - pointWhereDragBegan.x;
float yDragged = pointWhereDragEnded.y - pointWhereDragBegan.y;
NSLog(#"Drag ended at %f,%f",pointWhereDragEnded.x,pointWhereDragEnded.y);
NSLog(#"The user moved %f, %f",xDragged,yDragged);
}
}
drag.state will never be simultaneously UIGestureRecognizerStateBegan and UIGestureRecognizerStateEnded. This method should be invoked twice: once in each state.
As a result, in order to fix your issue, you'll need to persist pointWhereDragBegan outside the method scope. For example, you might use an instance variable.

objective-c: return value

I'm reading Stephen Kochan's "Programming in Objective-C" (I'm n0000b). Everything has been obvious to me until exercise 4-8.
It asks me to modify methods, in an "Accumulator" class created earlier in the chapter, to "return" the value of the accumulator when one of the math methods is used (basically it's a calculator). I took this originally to mean that I want the program to display the result whenever one of the methods is used (+, -, *, /), so I set it up to do so, so each line displays the cumulative result rather than just the final result:
[deskCalc setAccumulator: 0.0];
[deskCalc add: 200.]; //the result is displayed
[deskCalc divide: 100.0]; //the result is displayed
[deskCalc subtract: 1.0]; //the result is displayed
[deskCalc multiply: 5]; //the result is displayed
NSLog (#"The result is %g", [deskCalc accumulator]);
But after looking up other people's solutions, it appears that "returning the value of the Accumulator" means something different.
Can someone describe to me what returning a value means, and what purpose it serves? I have looked through the previous chapter a few times but it is still unclear to me how this will make the program behave differently.
Thanks!
-Andrew
The calculation methods you have in your accumulator class probably look something like this at the moment:
- (void)add:(float)aFloat {
result += aFloat;
NSLog(#"%f", result);
}
This method, in its current state, returns nothing (void). It outputs the current total on screen only. That's nice for an exercise, but in real-world programs, a calculation result will probably not be very useful if it's displayed on screen. Instead, you probably will want to do something else with the result, so you want the method to return it. For example, the NSString class has a method length. This method would not be very useful if it were to print the length of the string on screen. Instead, it returns the length, so the program can do something useful with this value (like checking that the string has the correct length):
int length = [tweet length];
if (length > 140) {
// display a useful error message
...
} else {
// tweet it :)
...
}
To modify your calculator methods to return something, you will (a) have to change the method signature to have a return value, and (b) to actually return this value.
In the method signature, simply change the return type to something other than void. In your example, the correct type would probably be float (or whatever type the calculator is using internally for its current result).
- (float)add:(float)aFloat {
...
}
To actually return the current value, you would add a return statement add the end of your method (before the closing })
return result;
(this assumes that result is the instance variable containing the current calculation result).
They are asking you to modify your add, divide, substract methods to return the value of the accumulator upon completion of the performed operation. My guess is that your original add/divide/etc methods defined a (void) return value, meaning they don't return any value from the function call. As a result you could not perform a execution similar to the following:
NSLog(#"Updated value: %g", [deskCalc substract: 1.0]);
Returning a value from a function means that not only could the function perform some type of operation, but it also returns some sort of value to the calling code. The purpose of returning a value is that it allows you to separate your code into logical components, allows for code reuse and increases maintainability of your code.
Here's an example of how it would be useful: let's say you need to calculate the square root of a number. Your code don't care how the square root is calculated, you just want the number. By using a function which takes in a value, calculates its square root and then returns the calculated value to the calling code, your code can worry about what it needs to do with the returned value of the function without having to worry about the logic itself.
Here is an example of a function which returns a NSString:
- (NSString *) getAString {
return #"String being returned";
}
Here is how you would use that function:
NSString *myString = [someObject getAString];
I hope this helps you along in your learning process.

Passing arguments by value or by reference in objective C

I'm kind of new with objective c and I'm trying to pass an argument by reference but is behaving like it were a value. Do you know why this doesn't work?
This is the function:
- (void) checkRedColorText:(UILabel *)labelToChange {
NSComparisonResult startLaterThanEnd = [startDate compare:endDate];
if (startLaterThanEnd == NSOrderedDescending){
labelToChange.textColor = [UIColor redColor];
}
else{
labelToChange.textColor = [UIColor blackColor];
}
}
And this is the call:
UILabel *startHourLabel; // This is properly initialized in other part of the code
[self checkRedColorText:startHourLabel];
Thanks for your help
Objective-C only support passing parameters by value. The problem here has probably been fixed already (Since this question is more than a year old) but I need to clarify some things regarding arguments and Objective-C.
Objective-C is a strict superset of C which means that everything C does, Obj-C does it too.
By having a quick look at Wikipedia, you can see that Function parameters are always passed by value
Objective-C is no different. What's happening here is that whenever we are passing an object to a function (In this case a UILabel *), we pass the value contained at the pointer's address.
Whatever you do, it will always be the value of what you are passing. If you want to pass the value of the reference you would have to pass it a **object (Like often seen when passing NSError).
This is the same thing with scalars, they are passed by value, hence you can modify the value of the variable you received in your method and that won't change the value of the original variable that you passed to the function.
Here's an example to ease the understanding:
- (void)parentFunction {
int i = 0;
[self modifyValueOfPassedArgument:i];
//i == 0 still!
}
- (void)modifyValueOfPassedArgument:(NSInteger)j {
//j == 0! but j is a copied variable. It is _NOT_ i
j = 23;
//j now == 23, but this hasn't changed the value of i.
}
If you wanted to be able to modify i, you would have to pass the value of the reference by doing the following:
- (void)parentFunction {
int i = 0; //Stack allocated. Kept it that way for sake of simplicity
[self modifyValueOfPassedReference:&i];
//i == 23!
}
- (void)modifyValueOfPassedReference:(NSInteger *)j {
//j == 0, and this points to i! We can modify i from here.
*j = 23;
//j now == 23, and i also == 23!
}
Objective-C, like Java, only has pass-by-value. Like Java, objects are always accessed through pointers. "objects" are never values directly, hence you never assign or pass an object. You are passing an object pointer by value. But that does not seem to be the issue -- you are trying to modify the object pointed to by the pointer, which is perfectly allowed and has nothing to do with pass-by-value vs. pass-by-reference. I don't see any problem with your code.
In objective-c, there is no way to pass objects by value (unless you explicitly copy it, but that's another story). Poke around your code -- are you sure checkRedColorText: is called? What about [startDate compare:endDate], does it ever not equal NSOrderedDescending? Is labelToChange nil?
Did you edit out code between this line
UILabel *startHourLabel;
and this line?
[self checkRedColorText:startHourLabel];
If not, the problem is that you're re-declaring your startHourLabel variable, so you're losing any sort of initialization that was there previously. You should be getting a compiler error here.
Here are the possibilities for why this doesn't work:
the label you pass in to checkRedColorText is not the one you think it is.
the comparison result is always coming out the same way.
... actually, there is no 3.
You claim you initialised startHourLabel elsewhere, but, if it is a label from a nib file, you should not be initialising it at all. It should be declared as an IBOutlet and connected to the label in the nib with interface builder.
If it is not a label in the nib i.e. you are deliberately creating it programmatically, you need to check the address of the label you initialise and check the address of the label passed in to checkRedColorText. Either NSLog its address at initialisation and in checkRedColorText or inspect it with the debugger.

What does it mean to return an object in a method?

I still cannot understand what does it mean to return an object in a method. What would its value mean?
If I have something like this:
-(ClassName *) methodName: (int) arg {
return arg;
}
I can't understand how an object can be returned through a method as the above. If someone can help me understand.
Thanks.
You would return an object by returning an object. For example, you could ignore the argument:
- (ClassName *)methodName:(int)arg {
return [[[ClassName alloc] init] autorelease];
}
You could turn the int into an object:
- (NSNumber *)methodName:(int)arg {
return [NSNumber numberWithInt:arg];
}
You could use the argument in some calculation to determine some property of the object returned. You could process the argument and return an object indicating the status of the calculation. And so on and so on. There's a practically unlimited range of ways you could return an object from a method. All it requires is that some object be created or accessed and then returned.
The above method returns a pointer to arg which is of type ClassName*.
I assume explaining the question would assume basic knowledge of how functions are called, how passed values are pushed on stack before function call and how return values is returned from a function.
In this specific case your arg variable is part of a class, meaning that it is stored in memory that is part of the object. When you return pointer to it you are pointing to a specific area of memory within the object.
Another option is to return copy of the value. It would mean make a copy and return it.
The difference is that if you return pointer to objects internal variable that object state could be modified from outside.
If you return copy that copy can be modified and the original object will not change.
Not sure if that helps, but you are asking about very basic software development topic which assumes some background knowledge.
Maybe specify what exactly you are looking for?
Think of methods like they are functions in math. In math, sin(180) is equal to 0. sin is the method, 180 is the argument and 0 is the return value of the method. An example of sin in objective-c might go like this:
-(double) sin:(double)angleInDegrees;
{
double sinValue;
//calculate the return value here and store it in sinValue.
//for example, if angleInDegrees is 180, then set sinValue to 0
return sinValue;
}
Returning objects is exactly the same. Look at this example:
-(NSString*) sayHelloTo:(NSString*)name;
{
return [NSString stringWithFormat:#"Hello %#!", name];
}
If I were to write it like a math function, then sayHelloTo(#"Tom") is equal to #"Hello Tom!". The only difference is that #"Hello Tom!" is an NSString object, not a double.