Sending a pointer to an interface property in Objective-C - iphone

Ok so I -roughly- want this code:
test1.m:
Foo *foo = [[Foo alloc] init];
foo.x = 1.0f;
[staticClass bar:*foo.x];
staticClass.m:
-(void)bar:(float *)argVar
{
*argVar += 1.0f;
}
So I'm pointing the argVar to a property of the Foo class. Obivously the current code doesn't work.
What's the proper syntax for/way to do this?

I think that the proper way to do it is this:
float tmp = foo.x;
[staticClass bar:&temp];
foo.x = tmp;
and StaticClass.m should look like this:
+(void) bar:(float *) argvar // < not plus instead of minus, denotes static method
{
*argVar = 1.0f;
}

x is a property of Foo, not a variable. A property is just a short-hand for a pair of get/set methods. It has no address, as such, and so cannot be passed around as you are trying to do.
The simplest work-around is to go through a local variable:
float d = foo.x;
[staticClass bar:&d];
foo.x = d;
Also note that you use &, not *, to take the address of a variable.

Options:
change Foo such that it has a float * property
change +[staticClass bar:] such that it takes and returns a float, updating your client code accordingly
use ivar_getOffset to find the location of the instance variable backing x in your Foo instance

Related

iPhone: Method overriding result

I have method overriding like below. Please ignore the way i written it may not be perfectly written, just for sample. But i want to know what would the output if i method overridden like this for variable "a".
-> base class
#interface A
{
int a=15;
}
-(int) myFunction;
#end
-> derived class
#interface B : A
{
int a=10;
}
-(int) myFunction;
#end
Lets image "myFunction" returns "a". Since, it does method overriding, when i call like,
B bObj;
bObj.a = ?
What should be the output 10 or 15 ?
I have assumed you are aware you can't declare variables in a header like that and the initialisation there is just for simplicity.
Similarly, your B bObj hasn't been initialised and isn't a pointer
bObj.a would return 10. So would [bObj myFunction]. You have overridden the method and told the compiler to disregard previous implementations of this method and use the new one.
Can you suggest what the output of this might be:
A *obj = [[B alloc] init];
NSLog(#"%d", [obj myFunction]);
or this:
B *obj = [[A alloc] init];
NSLog(#"%d", [obj myFunction]);
if child and parent both will return A then its method overriding ... but if class A's myFunction: returns A and class b's myfunction returns B or any reference type return type which has the same relation what ever there classes have means Parent and child relationship then this also know as overriding

Method accessing another method's local variables

Just a quick newbie question here. I have a method that calculates a value and stores the result in a double variable, this variable is also a local variable to that method.I also have a second method that does a separate calculation but this method needs the result in the first. How can I get the value from the first method while still keeping that variable hidden to the rest of the class? Below is an example of what I'm trying to get at.
-(IBAction)methodA{
double answer;
answer = 2 + 3;
}
-(IBAction)methodB{
double answerTimeTwo;
answerTimeTwo = answer * 2; //Problem arises here as I cannot access "answer"
}
They shouldn't be decorated as actions unless they're the result of a UIControl event.
Do it like this:
- (double)methodA {
double answer = 2.0 + 3.0; // don't really need the stack variable, but it's okay
return answer;
}
- (double)methodB {
double answerTimesTwo = [self methodA] * 2.0;
return answerTimesTwo;
}

Get all the variable names or attributes of a #interface

I want all the variables names or attributes of a interface or class in objective c.
I am able to get and set the value for a variable dynamically using valueForKey: message.
If you are looking to get all 'properties' for a class, you can utilize the Objective-C runtime to get this data:
unsigned int propertyCount, i;
objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);
for(i = 0; i < propertyCount; i++)
{
objc_property_t property = properties[i];
NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
}
free(properties);
With this object you can get all of the metadata associated with a given property. This isn't for the faint of heart though (and it is a C based API). Determining information about each property (like it's policy and type) isn't simple.
Take a look at the Objective-C Runtime Reference and in particular the class_copyIvarList and class_copyPropertyList functions. Use of these runtime functions should be what you're looking for.

How can I replace increment operators when using NSInteger and int properties

I am updating some old code to our new coding standards. In this code, the int variable was incremented with the old ++ operator. Now, the int variable is a property so using ++ isn't working so well. I'm not supposed to use dots and I'm not supposed to reference ivars directly.
Here is what I have come up with (totalHeads is the property of type int):
declaration section
#synthesize totalHeads = _totalHeads;
further down
[self setTotalHeads:[self totalHeads] + 1];
which replaces the old code of
_totalHeads ++;
Is there a more elegant way to do this?
(apologies if this is a duplicate question, I was having a hard time figuring out good search terms)
You can use the property and the postincrement operator. This code:
#interface Foo: NSObject
#property (assign) int bar;
#end
#implementation Foo
#synthesize bar;
#end
int main() {
Foo *foo = [[Foo alloc] init];
foo.bar = 3;
foo.bar++;
NSLog(#"foo.bar: %d", foo.bar);
[foo release];
return 0;
}
produces this result:
2011-06-21 21:17:53.552 Untitled[838:903] foo.bar: 4
It doesn't really matter that's a property - it's still an int and, unless you declare a different name for ivar associated with the property, you can still use totalHeads++;
If, as you've mentioned in the comments, you're not allowed to use dot syntax to access setter methods, then [self setTotalHeads:[self totalHeads] + 1]; is the only way to do it.
Coding standards that disallow use of language features under all circumstances are unproductive. Maybe you can use this example to make your case.
Based on a question about converting between NSInteger and int, I came up with the following:
- (NSInteger) incrementNSInteger: (NSInteger) nsInt byNumber: (int)increment
{
int integer = nsInt;
integer += increment;
NSInteger result = integer;
return result;
}
To use:
NSInteger one;
NSInteger two = [self incrementNSInteger: one byNumber: 1];
If you supply "byNumber" with -1, it'll decrement. Similarly, 2 increments by 2, -2 decrements by 2. (Why ++ and -- aren't sufficient baffles me).

How to instantiate a variable to call a method

Is their a way in c# to instantiate a variable into a method call without using a switch statement.
It sounds like you want to take a string and use that string to call a method on an object, this can be done with reflection without the need for a switch statement.
string methodName = "ToString";
var method = typeof(TypeYourMethodExistsOn).GetMethod(methodName);
method.Invoke(objectInstance, null);
I'm not too clear, either. If you don't want to use reflection (heavy sometimes), for dynamically calling methods using a variable, you could use something like a collection containing delegates as values and call them.
I use an extremely like dictionary object to dynamically call a known method based on string inputs.
psuedo code:
delegate void Del(int i, double j);
class MathClass
{
static void Main()
{
MathClass m = new MathClass();
// Delegate instantiation using "MultiplyNumbers"
Del d = m.MultiplyNumbers;
Hashtable ht = new Hashtable();
ht.Add("mult", d);
// Invoke the delegate object.
System.Console.WriteLine("Invoking the delegate using 'MultiplyNumbers':");
for (int i = 1; i <= 5; i++)
{
((del) ht("mult"))(i, 2);
}
}
// Declare the associated method.
void MultiplyNumbers(int m, double n)
{
System.Console.Write(m * n + " ");
}
}