How to call a non-void function? Xcode - iphone

How do I call a non-void function? Normal [self methodName]; works. But how do I do this for a method that returns an NSString. I keep getting an error. For example:
+ (NSString *)formulateYQLRequestFor:(NSArray *)tickers
How do I call this? [self formulateYQLRequestFor]; gives me an error.
Sorry about the formatting, for some reason safari won't let me indent.
Thanks!

+ designates a class function. You call it with the class name, not an instance.
Instead of:
[self formulateYQLRequestFor:myArray];
Do this:
[MyClassName formulateYQLRequestFor:myArray];
Alternatively, you can do this:
[[self class] formulateYQLRequestFor:myArray];
You don't have to do anything with the return value if you don't want to. At least with ARC, the return value will be automatically released. However, since it's unlikely that the function does anything on its own, you probably should do something with the return value:
NSString *returnValue = [[self class] formulateYQLRequestFor:myArray];
// Do something with returnValue
Finally, if you want to call the function without passing in an array, you still need the array parameter, but perhaps the function will accept nil for the array:
NSString *returnValue = [[self class] formulateYQLRequestFor:nil];

There are two problems with your call to [self formulateYQLRequestFor];
Firstly, the method takes a parameter, which you haven't provided. Because of this, the compiler is looking for the method called formulateYQLRequestFor instead of formulateYQLRequestFor: This is significant, because the : is part of the method name in Objective-C. So you are trying to call a method that doesn't exist.
Secondly, self is sending a message to an instance of your class. The + in the method signature indicates that you have a class method, and so self does not respond to the method you are trying to call.
The correct way to do this is:
NSString *resultString = [[self class] formulateYQLRequestFor:someArray];
where someArray is a valid NSArray parameter.

I don't know what - (NSString *)formulateYQLRequestFor: does with the NSArray, but if it isn't necessary you can just call [self formulateYQLRequestFor:nil];. Alternatively you can call it with an empty array [self formulateYQLRequestFor:[NSArray array]];.

Related

Calling a method in another method?

I've got a delegate method which just has a bit of code in there that puts a % sign on the end of the number entered.
- (void)textFieldDidEndEditing:(UITextField *)UItextfield {
NSString *oldTextFieldValue = UItextfield.text;
UItextfield.text = [NSString stringWithFormat:#"%# %%",oldTextFieldValue];
}
Could I instead of having that, have the following action
-(IBAction)Calculate:(UITextField *)UITextfield;
{
NSString *oldTextFieldValue = UItextfield.text;
UItextfield.text = [NSString stringWithFormat:#"%# %%",oldTextFieldValue];
}
And then in the Delegate function, call that action? Something like
-(void)textFieldDidEndEditing:(UITextField *)UItextfield {
[self Calculate:self]
}
I tried that, it doesn't work. I know it'll get me to the same result but I just want to know if it can be done. I think i'm asking can a method (Calculate) be called in another method (textFieldDidEndEditing) and how.
You are providing self as the method argument which is the instance of the class you are in. Which in this case is wrong since the method argument should be an instance of UITextField. Try instead [self Calculate:UItextfield] in your method.
Calling other methods from methods happen all the time in most programming languages.
It's a great way to split code up and reuse code in different places without having to copy/paste.
(This might be too basic for you. Sorry in that case)
Things may be easier to understand if you use standard naming conventions too. ('likeThis' for variables and method names; 'LikeThis' for class names)
- (void)textFieldDidEndEditing:(UITextField *)textField {
NSString *oldTextFieldValue = textField.text;
textField.text = [NSString stringWithFormat:#"%# %%",oldTextFieldValue];
}
textField here, is the pointer to the UITextField object which just finished editing.
You want to pass this object to your new 'other' method.
[self calculate:textField];
self is a pointer to an instance of the current class. For example, in a UIViewController subclass called 'MyViewController', self refers to the current instance of this class.
Since the -calculate method is an instance method (beginning with a '-') it requires you to use self. The variable textField is passed after the colon.
- (void)calculate: (UITextField*)textField {
NSString *oldTextFieldValue = textField.text;
textField.text = [NSString stringWithFormat:#"%# %%",oldTextFieldValue];
}
Use only the IBAction keyword when you want the method to be called from a UIComponent in an xib or storyboard.

NSManagedObject Incompatible pointer type warnings

Let me make sure first I have X-Code 4.3.2 version and iOS 5.1 SDK. I have below methods used in my project for core-data operation. Both method giving same warning. i.e "Incompatible pointer types returning 'NSManagedObject *' from a function with result type 'NSManagedObject <Protocol> ".
Method A:
- (NSManagedObject<Protocol> *)newMOforNilMOC
{
return [[NSManagedObject alloc] initWithEntity:[self entityDescription] insertIntoManagedObjectContext:nil];
}
For method method A I just do typecasting and added (NSManagedObject<Protocol>*) then warning get removed as stated below.
- (NSManagedObject<Protocol> *)newMOforNilMOC
{
return (NSManagedObject<Protocol> *) [[NSManagedObject alloc] initWithEntity:[self entityDescription] insertIntoManagedObjectContext:nil];
}
Method B:
+ (NSManagedObject<Protocol> *) newInContext:(NSManagedObjectContext *)context
{
return [[NSEntityDescription insertNewObjectForEntityForName:[[(NSManagedObject<Protocol> *)self class] entityName] inManagedObjectContext:context]retain];
}
For method B when I do typecasting it will not work hence I just change the name of method from newInContext to AddnewInContext (Found somewhere when googled) then warning got removed.
I have following Questions:
If first method is required typecasting then why second one is not working with that solution?
What is the exact meaning of changing the name of method. Is this proper way to remove above warning? Why typecasting not working in
method B?
This could be complicated one but feel free to leave comment if you have any doubt. Because I want to know the difference, at least I get to learn some new thing about core data.
I think you are using 'self' in a class method. You should use the class itself. Let me show by code
+ (NSManagedObject<Protocol> *) newInContext:(NSManagedObjectContext *)context
{
//Usage of [self class] is not correct, as self points already to a class.
NSEntityDescription* desc = [NSEntityDescription entityForName:#"myObjectName" inManagedObjectContext:context];
return [[NSEntityDescription insertNewObjectForEntityForName:desc inManagedObjectContext:context]retain];
}
You can't cast a class type to a 'id' type, which is the one that self points to if you are inside an object method, not a class method. I don't think any method renaming solves any warning.

custom setter for NSString

I have a NSString called fontType
and I am trying to have a custom setter for it:
- (void) setFontType:(NSString *) fType
{
if (self.fontType != fType){
[fontType release];
self.fontType = [fType retain];
//some more custom code
}
}
Is there any issue with this?
A few things that stand out for me:
do not use self. inside of custom accessors. access the variable directly
it's better use copy semantics for properties of a type that has a
mutable subtype
be careful with whatever is // some more custom code
My personal style preferences are like so:
-(void)setFontType:(NSString *)fontType_ {
if (fontType == fontType_) return; // get out quick, flatten the code
[fontType release];
fontType = [fontType_ copy];
// some more code
}
Cocoa with Love has a good article on this topic. It's worth a read.
When you do self.fontType = newFontType, you are doing [self setFontType:newFontType] (just with a different syntax), this means you are calling the method inside itself.
This is called recursion, but in this case, you don't have a base case in which the method will stop calling itself, so my guess is that this method will call itself until the app crashes. In short, recursion is not something you want here.
Just replace self.fontType = [fType retain] with fontType = [fType retain] (Assuming the var linked to the fontType property is called fontType as well).
PS. At the end of the question you asked
Is there any issue with this?
If you didn't try this, then you shouldn't even be asking that here on StackOverflow, and if you did try it, then you should have realized that this method didn't work, so that last line is pretty meaningless. Just saying.

Objective C calling method dynamically with a string

Im just wondering whether there is a way to call a method where i build the name of the method on the fly with a string.
e.g. I have a method called loaddata
-(void)loadData;
to call this i would normally call it like
[self loadData];
But i want to be able to call it dynamically with a string e.g.
NSString *methodName = [[NSString alloc] initWithString:#"loadData"];
[self methodName];
This is a stupid example but i hope you get my point. I am using it for databinding classes that I am setting up for my IPad application. Hard to explain but to get it to fire I need to work out how to call a method with a string.
Any ideas?
Thanks
You can try something like
SEL s = NSSelectorFromString(selectorName);
[anObject performSelector:s];
You can use the objc_msgSend function. It takes two parameters, the receiver and the selector to send to it:
objc_msgSend(self, someSelector);
You'll need to turn your string into the appropriate selector using NSSelectorFromString:
NSString *message = [self getSomeSelectorName];
objc_msgSend(self, message);
The method also takes a variable number of arguments, so you can send messages with any number of arguments.
NSString *message = [self getSomeSelectorNameWithManyArguments];
objc_msgSend(self, message, arg1, arg2, arg3, arg4);

How To Pass a Dictionary To a Function

Alright, so I think I'm doing this the right way. I'm new to objective-C, so I'm not sure about the syntax... I have a set of code that I need to call multiple times, from different files. So I made a new class that has a method in it that I'll call and pass it the values that it needs.
Because I am passing different values I've put them in a dictionary and decided to just pass the dictionary. Here is that code:
NSNumber *testNum = [NSNumber numberWithInt:varMoney];
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:#"OMG, Object 1!!!!" forKey:#"1"];
[dictionary setObject:#"Number two!" forKey:#"2"];
[dictionary setObject:testNum forKey:#"3"];
This code creates a test variable, and then puts it into the dictionary "dictionary." That all works, I have my nice little dictionary. However, now I need to create the class and it's method that will recieve the dictionary, and do something with it.
This is my class header file:
#import <UIKit/UIKit.h>
#interface EndOfTurnObjC : UIView {
}
#end
And this is the implementation file:
#import "EndOfTurnObjC.h"
#implementation EndOfTurnObjC
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (void)dealloc {
[super dealloc];
}
#end
I haven't created any of the real code, because I'm not sure how to do the passing. I need to create a function (Method?) in the class that will take a Dictionary has a parameter, and then return the dictionary.
I also have no idea how to call such a function because it's in the class. So, the questions are:
1: How do I define the method in the class to accept the dictionary as a parameter (and then perhaps some example code to pull out one of the objects in a dictionary, so I can be sure it works)
2: How do I return the dictionary at the end of the method?
3: How do I call this method, in the class, from another class? (I know it involves making an object of thing class and calling the method of the object... I think, but I'm not sure about the syntax.)
Please include relavent code for the 3 files (header, implementation, and the other class that I call from). Thank you so much, I've been working on this particular problem for a while now.
Apple's The Objective-C Programming Language is a good and pretty concise reference for Objective-C syntax. What you want is just a normal method that takes an NSDictionary as a parameter. So as given in that document:
A message with a single argument affixes a colon (:) to the selector name and puts the argument right after the colon. This construct is called a keyword; a keyword ends with a colon, and an argument follows the colon, as shown in this example:
[myRectangle setWidth:20.0];
So a method call to pass dictionary would look like:
[someObject setAttributes:dictionary];
In the header:
-(NSMutableDictionary *) doSomethingWithDictionary:(NSMutableDictionary *) aDict;
in the implementation:
-(NSMutableDictionary *) doSomethingWithDictionary:(NSMutableDictionary *) aDict{
//do something with the dictionary
return aDict;
}
To call the method:
NSMutableDictionary *returnDict=[EndOfTurnObjC doSomethingWithDictionary:dictionary];
Note that as a matter of good design you wouldn't want to pass a mutable dictionary around like a token. That is asking for trouble. Instead pass static dictionaries and get another dictionary back.
You also shouldn't be passing data to a UIView. Instead, your UIViewController should process the data and then populate the view's UI elements as needed.
if you just want to do stuff to your dictionary u just
-(void) changeMyDictionary:(NSMutableDictionary * ) dictionary_
{
[dictionary_ doStuff];
....
...
}
no need to return the dictionary.