Error in function call - iphone

I have the following function:
-(void) CalLevels: (NSMutableArray *)rPrices: (NSMutableDictionary *) rLevels: (float) nClose: (float) nHigh: (float) nLow: (float) nOpen {...}
I am calling the above function as follows:
[self CalLevels:rm.rPrices rLevels:rm.rLevels nClose:nCloseD nHigh:nHighD nLow:nLowD nOpen:nOpenD];
I get the warning method not found. Thanks for any help.

You should call it like that:
[self CalLevels:rm.rPrices :rm.rLevels :nCloseD :nHighD :nLowD :nOpenD];
or change the method declaration, since rLevel and its friends are the internal method name of the variables, not part of the method name.
The correct way is either the one above, or change the method signature:
-(void) CalLevels: (NSMutableArray *)rPrices rLevels: (NSMutableDictionary *) rLevels nClose: (float) nClose nHigh: (float) nHigh nLow: (float) nLow nOpen : (float) nOpen {...}

Your method declaration is busted. You write:
-(void) CalLevels: (NSMutableArray *)rPrices: (NSMutableDictionary *) rLevels: (float) nClose: (float) nHigh: (float) nLow: (float) nOpen
This declares a method named CalLevels::::::. The rLevels, nClose and all that are parsed as the parameters' names. You probably meant to declare one named alLevels:rPrices:rLevels:nClose:nHigh:nLow:nOpen:. That would look more like this:
- (void)CalLevels:(NSMutableArray *)levels rPrices:(NSMutableDictionary *)rPrices rLevels:(float)rLevels nClose:(float)nClose nHigh:(float)nHigh nLow:(float)nLow nOpen:(float)nOpen
(I'm guessing that nOpen is meant to be a float.)

What #MByD wrote will work but if you want to adhere to the Naming Conventions you need to rename your method. Right now your method is named CalLevels:::::: and rLevels, nClose, etc. are the parameter names that are not part of the name. If you want to follow the Naming Conventions, you need to:
Start the name with a lowercase letter. CalLevels... is wrong, calLevels... is right.
Use keywords before all arguments. calLevels:::::: is wrong, calLevels:rPrices:rLevels:nClose:nHigh:nLow:nOpen: is right.
Resulting in something like this:
-(void)calLevels:(NSMutableArray *)rLevels rPrices:(NSMutableDictionary *)rPrices nClose:(float)nClose nHigh:(float)nHigh nLow:(float)nLow nOpen:(float)nOpen;

Related

What is the role of selector in UILocalizedIndexedCollation's sectionForObject:(id)object collationStringSelector:(SEL)selector method

I am a beginner of iOS development and while going through this document (iOS Developer Guide about configuring a TableView with Indexed List) I came across this:
// Listing 4.7
for (State *theState in statesTemp) {
NSInteger sect = [theCollation sectionForObject:theState collationStringSelector:#selector(name)];
theState.sectionNumber = sect;
}
I could not figure out the selector (#selector(name)) and its purpose, nor could I find the method with the name passed in the selector i.e. name. I googled for examples to find a better explanation, and came across this example.
In the code listing, there is a statement which is a method call:
    
self.tableData = [self partitionObjects:objects collationStringSelector:#selector(title)];
now the selector is called title. I have not been able to find a better explanation, and my question is what is the purpose of this selector and the method referred by this selector, and what should it do and return.
In general
With the #selector(title:) you define which method will be called.
in my example it will call
- (void) title:(id)someObject {}
Be carefull with the semicolon at the end! If you have a semicolon at the end you method will have parameters like mine above.
Your code states just #selector(title) and will call a method title without a parameter like this:
- (void)title {}
Specific to UILocalizedIndexCollation
The docs state:
selector
A selector that identifies a method returning an identifying
string for object that is used in collation. The method should take no
arguments and return an NSString object. For example, this could be a
name property on the object.
So i would suggest you implement it like this
self.tableData = [self partitionObjects:objects collationStringSelector:#selector(title)];
...
- (NSString *)title {
NSString *title;
// some code to fill title with an identifier for your object
return title;
}
Try replace the title with self:
self.tableData = [self partitionObjects:objects collationStringSelector:#selector(self)];
worked for me

Incompatible pointer types sending 'NSString *' to parameter of type 'NSInteger *' (aka 'int *')

i have 2 file, data.h and data.m with connection db and method db.
When i implement a method i have a warning
*Incompatible pointer types sending 'NSString *' to parameter of type 'NSInteger *' (aka 'int ')
This is my code.
in data.h
- (id)initCity:(NSString *)pathDB: (NSInteger *)id_city: (NSString *)type;
- (void)getCity:(NSString *)dbPath:(NSInteger *)id_city;
in data.m
- (id)initCity:(NSString *)pathDB: (NSInteger *)id_city: (NSString *)type
{
[self getCity:pathDB: id_city: type];
return self;
}
- (void)getCity:(NSString *)dbPath : (NSInteger *)id_city : (NSString *)type { .......
......
}
and where i call my method
NSString *mystring = #"string";
dataCity = [[Data alloc] initCity: defaultDBPath: selectedItem :mystring];
NSMutableDictionary *dictionary = [dataCity objectAtIndex:0];
where wrong?
Thanks
frank
First of all NSInteger is an integer type, not an object, so you don't need a pointer.
Secondly, your method declarations are malformed. It should be something like this:
- (id)initCityWithPath:(NSString *)pathDB andId:(NSInteger)id_city andType:(NSString *)type;
- (void)getCityWithPath:(NSString *)dbPath andId:(NSInteger)id_city;
- (id)initCity:(NSString *)pathDB: (NSInteger *)id_city: (NSString *)type;
The name of this method is initCity::: which takes three parameters, pathDB, id_city and type. This is probably not what you want and probably not what anybody who has to look at your code wants. Objective-C gives you the ability to name the parameters of methods, and any method that does not name its parameters will always be suspicious1. For most Objective-C developers, initCity::: is not a good name for a method.
Secondly, initialiser methods should always start by invoking [super init] and assigning the result to self. There is seldom a reason not to do this (for example, when you are creating your own root class).
Third, your initialiser calls getCity::: (another poor name) which returns void and takes two input parameters and possibly one in/out or output parameter, this does not look like it will initialise your object properly. It is rare to see a method start with get unless it has an output parameter (e.g. getBytes:length:). In your case I think you may be using the wrong type, NSInteger is an alias for a 32-bit integer on 32-bit platforms and a 64-bit integer on 64-bit platforms. NSInteger * is therefore a pointer to such an integer. It's confusing, but this is different from NSNumber which is a class that encapsulates things like NSInteger.
No offence intended here, but from the code you provided above it seems that you lack some understanding of fundamental aspects of Objective-C. I would recommend reading a good book, following some reputable tutorials and having a look at some of Apple's example code before progressing.
1: For older runtimes, the root Object class declared in objc/Object.h had two methods called forward:: and performv:: which both contained an unnamed parameter, and these were used for message forwarding.

Can I declare a method with arguments with unknown types?

I'm building a bunch of functions that will make my core data calls a bit nicer, and not so bloated.
Lets say I have a method that looks like this:
- (NSArray*)retrieveDataFrom:(NSString *) name where:(NSString *) where is:(NSString *) is {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(%# = '%#')", where, is];
return [self retrieveDataFrom:name withPredicate:predicate];
}
and then sometimes I want to do something like this (for example):
[self retrieveDataFrom:#"table" where:#"id" is:int 2];
instead of this:
[self retrieveDataFrom:#"table" where:#"id" is:#"2"];
Is there a way to get a method to accept an argument without knowing its type?
Not directly. You can declare the input as NSObject * so it can take a NSString * or a NSNumber *, but you're still stuck using NSNumber's ugly syntax.
[self retrieveDataFrom:#"table" where:#"id" is:[NSNumber numberWithInt:2]];
However, better syntax is coming soon in the form of Clang Language Extensions.
When these land, you'll be able to write this instead:
[self retrieveDataFrom:#"table" where:#"id" is:#2];
At present, the LLVM website says these will be in llvm 4.0. The smart money says this will be in Xcode 4.4, but I doubt Apple is beholden to a statement on the LLVM website.
No. At best, you can let it accept any obj-c type by using id, but you cannot have an argument accept any type. The only exception is using varargs, but even there the method needs some way of knowing what type of argument to expect before it even looks at the argument (e.g. printf-style methods use the format string to figure out what the type of the argument is going to be).
If you use id, your method will look like
- (NSArray *)retrieveDataFrom:(NSString *)name where:(NSString *)where is:(id)is;
And your usage will look like
[self retrieveDataFrom:#"table" where:#"id" is:[NSNumber numberWithInt:2]];
Or with the new objective-c literals,
[self retrieveDataFrom:#"table" where:#"id" is:#2];
Just use (id) instead of (NSString *)
- (NSArray*)retrieveDataFrom:(NSString *) name where:(NSString *) where is:(id) is
Use (id)
- (NSArray*)retrieveDataFrom:(id) name where:(id) whereIs:(id)is {
...
}
or pass (NSArray*)
- (NSArray*)retrieveDataFrom:(NSArray*) params {
...
}

Passing argument makes pointer from integer without a cast

I wrote a function that looks like this:
- (void)changeText:(NSUInteger)arrayIndex;
Let's just say that's a method in the class Label. Let's say I have an array of Label objects. I call the function like this:
[[labels objectAtIndex:0] changeText:1];
or like this:
NSUInteger index = 1;
[[labels objectAtIndex:0] changeText:index];
Why does it give me the warning: Passing argument 1 of 'changeText:' makes pointer from integer without a cast? The code executes fine.
*EDIT*
Calling the function these ways does not give a warning:
[[labels objectAtIndex:0] changeText:0]; //arrayIndex is 0
Label *object = [labels objectAtIndex:0];
[object changeText:1];
More likely than not, you aren't #importing the header file containing the definition of changeText: into whatever .m file is calling it and, thus, the compiler hasn't seen the method declaration and doesn't know what the argumentation is supposed to be.
Or you have a changeText: method defined that does take an object reference as an argument and the compiler is seeing that before compiling the call site.
Somehow it thinks that changeText: takes a pointer as an argument. Probably because objectAtIndex: returns an NSObject and Objective-C doesn't know, a priori, what class's signature to apply to it.
Why don't you assign the result of objectAtIndex: to a Label*, then apply changeText: to it?
Like so:
Label* label = (Label *)[labels objectAtIndex:0];
[label changeText:1];

Dot notation - Does it take parameters?

Is it correct if I say that
[anIstance aMethod];
is equivalent to
anIstance.aMethod; --?
If it is the case, what about methods which take one ore more parameters?
Does the following statement
[anIstance aMethod : aParameter];
have an equivalent dot notation?
I have tried with
anIstance.aMethod : aParameter;
anIstance.aMethod(aParameter);
And they don't seem to work (compile time errors)
If there is not a way to invoke a method with parameters in dot notation what about the synthesized setter methods (which, as far as I know, by definition take an argument)?
If I have a synthesized property, does the following statement
anIstance.aProperty = anotherObject;
invoke the relative setter method? Or does it call the getter method?
The other answers convey the general idea, but I'd like to explicitly state that dot notation and properties are separate concepts. Dot notation is intended for setters (methods named setSomething: that take a single parameter) and getters, and can also be used for any method that takes no parameters (though it's very poor style to use it for an action like myObject.doSomething).
Properties are designed to declare getters and setters more easily, and even generate the code for you.
So the two concepts are related, but it's entirely possible (and not always poor style) to use dot notation with your very own getters and setters, that you wrote by hand. It's also entirely possible (and usually perfectly acceptable!) to use properties, even with getters and setters generated for you, with normal bracket syntax, and not dot notation.
But to address the original question, no, dot notation does not take parameters. It's specifically designed for use with methods that don't take parameters.
This is covered in Apple's "The Objective C Programming Language" guide:
#interface MyClass : NSObject
{
float value;
}
#property float value;
#end
You can think of a property
declaration as being equivalent to
declaring two accessor methods. Thus
#property float value;
is equivalent to:
- (float)value;
- (void)setValue:(float)newValue;
dot-notation is only valid for properties. Properties are declared with the #property declaration in Objective-C
like this:
interface MyClass {
NSString * x;
}
#property (copy) NSString *x;
implementation:
#synthesize x;
// this will generate a setter and getter method:
// - (NSString *) x {}
// - (void) setX:(NSString *)value {}
then you can use:
MyClass *obj = [[MyClass alloc] init];
obj.x = #"test";
But this only works for properties. Not for methods.
Dot notation is just syntactic sugar for properties in Objective-C, you can't use it for general method calls.