When to use . parameter and when to use [ ] to call a function in IOS - ios5

In iOS I have some confusion when calling a function.
-(void) function:(NSString*) str
{
selectedstring = str;
}
When calling the function.
When should I call like:
self.function = #"My name";
and
[self function:#"My name"]
What is the difference between (.) parameter and [ ]
in iOS function calling?

myVar = self.property is equivalent to myVar = [self property]
self.property = anotherVar is equivalent to [self setProperty:anotherVar]
Which you use is a matter of style.
Some people will tell you that the dot syntax should only be used for things that are actually defined as properties (with #property). I disagree with this. My opinion is that the dot syntax should be used whenever you're calling something that gets or sets a value, with minimal other side effects. Whether you have written the method yourself or synthesized a property to auto-generate it is not important: the important thing is whether it is related to getting and setting a value.
So myArray.count is fine, despite it not being a #property in the header file. But myURLConnection.start is not, since that doesn't return a value and is related to performing an action.
People do disagree with this. Some people don't like using dot syntax at all, since it could be confused with accessing the members of a struct (which also use .). Others are happy to use dot syntax for #propertys, but not for other methods.

Related

difference between object.variable and object->variable

What is the difference in using object.variable and object->variable? When should I use object->variable?
As Objective C is a superset of C when using '->' syntax (which is similar to (*obj).var) you are accessing the instance variable (ivar) like in C-structure (well, classes in ObjC are just fancy C-structures).
Thus using the '.' implies that you're accessing the property. Properties is the feature that was added in Objective C 2.0 and allows you access your ivars via setter/getter methods, that could be created automatically (using #synthesize) or you can provide your own implementation. BTW it is absolutely not necessary for properties to have corresponding ivar. For example in #interface you declare:
#interface Ololo : NSObject {
//NOTE: there is no ivar named someText or _someText or whatever you want
}
#property(nonatomic) NSString* someText;
#end
Then in #implementation:
#implementation Ololo
#dynamic someText; //we're using this to tell compiler that we will provide getters/setters ourselves and it doesn't need to generate them (though it is not necessary to do that)
-(NSString*) someText {
return [NSString stringWithContentsOfFile: #"some_file_path"]; //we actually get value from file
}
-(void) setSomeText:(NSString*) str {
[#"asdas" writeToFile: #"some_file_path" atomically: YES];
}
#end
Actually you can do whatever you want in those methods. So using '.' is just shortcut for [obj setSomeText: #"hello"].
If you use . you are accessing a property of the class which you defined using #property and created with #synthesize. If you use -> you just access an instance variable, but its not really something you should use a lot. And the use is very limited. So don't make it difficult for yourself and use properties with .
The indirection operator (->) is inherited from C and can be used as a shorthand for accessing fields in a structure, to which you have a pointer.
As an example...
typedef struct IPhone {
int serialId;
} IPhone;
Here I have a traditional C struct which I can instantiate as follows...
IPhone *phone = (IPhone*)malloc(sizeof(IPhone));
Now to access its fields I can either do it the long way...
*(phone).serialId = 1123432324;
Or I can use the shorthand indirection operator...
phone->serialiId = 1123432324;
At the heart of every ObjectiveC class is a C struct. So what you're doing when you use the indirection operator is to jump back to old C syntax to backdoor into the underlying representation. It works, but it's not the prescribed ObjectiveC way.
object->variable is direct access to the variable. object.variable is a method call to the getter accessor method '-(id)variable'or setter accessor method '-(void)setVariable:(id)value' depending on context. You must write the accessor methods yourself or use #synthesize to generate them in order to use dot syntax.
Good programming practice dictates you always use accessor methods to access an instance variable from another instance. ie, dont use ->

Why my array instance is out of scope?

Could some one tell me why my array is out of scope?
Here's my class:
// Paper.h
#interface Paper : NSObject {
NSMutableArray* items;
}
#property (retain) NSMutableArray* items;
// Paper.m
#import "Paper.h"
#implementation Paper {
#synthesize items;
}
// ParserUtil.m
#implementation ParserUtil {
+(Paper*) parsePaper:(NSString*)file {
...
Paper* paper = [[[Paper alloc] init] autorelease];
// does the following line is the best practice?
paper.items = [[[MutableArray alloc] init] autorelease];
Item* item = ...; // create item instance
[paper.items addObject:item];
return paper;
}
// call the parser method
...
Paper* paper = [[ParserUtil parsePaper:#"SomeFile"] retain];
// when run to this line, the paper.items is out of scope
// seems all the items in the array are dispear
NSMutableArray* items = paper.items;
...
Could someone point out what is wrong here?
Many thanks!
It isn't.
An object cannot be out of scope, because objects do not have scope. What they can be is unreachable, which is what happens when you don't have any variables holding the object's pointer.
Variables can be out of scope. You can only use a variable within the same scope in which you declared it; you can't begin a compound statement, declare a variable, finish the compound statement, and use the variable, and you can't declare a variable in one function or method and then use it in a different one.
You said in your other question that it's the debugger telling you the variable is out of scope. This means one of two three things:
The variable really is out of scope. Move the variable or move the code that uses it, or just interrupt the debugger earlier (with a breakpoint, if necessary).
The debugger is just being stupid. This happens a lot. Try the po command or sprinkle your code with NSLog statements instead.
You're trying to examine a property-access expression. A property-access expression, by definition, must send an accessor message, which may have side effects; for that reason, the debugger won't do that just for you hovering over the expression, because that's too easy to do by accident. You must use the po command in the Debugger Console to send the accessor message and print the description of the result.

iPhone Int with NSObject &/causes class can't reference itself

I've got a function called updateTheValue() that I have called using [self updateTheValue] for a while now. Two things happened recently; I added the method calling in the viewDidLoad() method and it spit out a warning saying my class may not respond to this. Second, I want to pass objects to updateTheValue() like strings, but mostly ints, so I declared an NSObject to pass into the method. Can an int fit into an NSObject slot, or what should I use instead?
I would have posted these seperately but they seem to be related since after updating updateTheValue() to accept an NSObject every reference to this function turns out the error that my class "May not respond to -updateTheValue"
You could make your method like this:
-(void)updateTheValue:(NSObject *)anObject
// or use -(void)updateTheValue:(id)anObject
{
if ([anObject isKindOfClass:[NSString class]]) {
// Do your string handling here
}
else if ([anObject isKindOfClass:[NSNumber class]]) {
// Do your number handling here
}
}
Use it like this:
[self updateTheValue:[NSNumber numberWithInt:42]];
I'd suggest doing two different methods though, i.e. updateTheValueWithInt: and updateTheValueWithString: making it easier to read and understand.
Make sure you make the method signature visible before using them, so that the compiler knows what this does.
If you use separate methods you can use int directly without wrapping them into NSNumber objects.
First problem:
updateTheValue() must be declared before you try to call it.
You can either move the definition of function before the calls to it, or add a prototype at the top - eg, add:
(void) updateTheValue;
near the top.
Second problem:
Use an NSNumber, eg [NSNumber numberWithInt:45];

What type of variable do I use to store mathematical operator?

I'm trying to put buttons that have operators on them, like / * +, etc. I want to store the operator in such a way that I can use it in an expression, like 1 var 2 = 8
I would like to avoid having to use a different method for each operator, so an operator var would be my best option, I think. Objective-C for iPhone
The usual OO way to do this is to create a class "mathOperator" that has a method "performOp" taking two parameters, then inherit different classes from it that represent the different operations. I'm not an expert in objective-C, so my syntax is probably a bit off, but I think you'd write something like:
result = [var On:arg1 And:arg2];
for example
result = [var On:2 And:3];
would set result to 5 or 6 depending on whether var was set to add or mul. The implementation would look like (again, very roughly):
#interface Add: mathOperator
-(int)On: (int)arg1 And: (int)arg2;
#end
...
#implementation Add
-(int)On: (int)arg1 And: (int)arg2 {
return arg1 + arg2;
}
and of course similar for the other operators:
#implementation Mul
-(int)On: (int)arg1 And: (int)arg2 {
return arg1 * arg2;
}
Read ch 5 in Cocoa Design Patterns. The approach used is to define "Command" classes that will perform each operation defined as a class method "execute". Then you can dynamically perform the operation by obtaining the appropriate class by using the following
commandName = [NSString stringWithFormat:#"MY%#Command", [commandString capitalizedString]];
commandClass = NSClassFromString(commandName);
result = [commandClass executeWithXValue:x yValue:y];
The way i'd do it is to make methods for each type of arithmatic and pass the numbers into them. Then instead of all that with the variable call the function.
There's no such thing in C. You'll have to use a selector which invokes a method to do what you want.

Setter Getter oddness #property

I am having a really odd problem trying to set a simple float value to 1.
My property:
{
float direction;
}
#property(nonatomic)float direction;
Which is synthesized:
#synthesize direction;
I then used the following code:
- (void)setDirection:(float)_direction {
NSLog(#"Setter called with value of %f",_direction);
self->direction = _direction;
}
For testing purposes...
When I try to change the value with this,
[[w getCharacter] setDirection:1.0f];
where [w getCharacter] gives this:
return [[[self scene] gameLayer] player];
I get the warning, "setDirection not defined."
If I switch to dot notation([w getCharacter].direction), I get "confused by earlier errors, bailing out".
Here is where the weirdness starts. When I try to change the value, the debug message displays _direction = 0.00000. When I check the number later, its still 0.000. I am clearly trying to change it to 1, why is this not working?
The simplest explanation is that [w getCharacter] doesn't return the class of object you think it does. Only the class that has direction defined for it can respond to the message. You should test this by explicitly calling it with the class it defined for.
It is possible you did not include the header that defines the method.
Two probably unrelated issues:
The self->direction construction will work for a scalar value but it does an end run around the entire class concept. In this case just use: 'direction=_direction;` and it will set it directly.
Apple reserves all names that start with underscores for its own internal use. You should not use them because Objective-c has a global name space. It's possible that you can accidentally use an Apple variable that is defined deep within a framework. (This is why framework constants all start with NS,CF,CA etc.)
[Note: In the Comments, the author says to ignore this answer.
self.direction = 1; is syntactic sugar for
[self setDirection: 1];
when you call
-(void)setDirection:(float)_newDirection {
self.direction = _newDirection;
}
You seem to be telling the compiler or preprocessor to set up a recursive loop for you. The preprocessor (I think) changes it to this:
-(void)setDirection:(float)_newDirection {
[self setDirection: _newDirection];
}
If you call it simply
-(void)setDirection:(float)_newDirection {
direction = _newDirection;
}
the assignment should work (it worked for me just now)