method syntax in objective-c [duplicate] - objective-c

This question already has answers here:
Method Syntax in Objective-C
(4 answers)
Closed 3 years ago.
I'm a .NET programmer new to objective-c, and I'm struggling to understand some nuts and bolts syntax. For example, how should I parse this method signature:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
I understand what the "-" char means, and (UITableViewCell *) defines the return type. But the rest has me confused.

(1) (2) (3) (4) (5) (6) (7) (8)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
"-" Defines an instance method
Returns UITableViewCell pointer
First part of the method signature named "tableView"
Takes a UITableView pointer
With the local variable name "tableView"
Second part of the method signature "cellForRowAtIndexPath"
Takes a NSIndexPath pointer
With the local variable name "indexPath".
The actual method signature is: tableView:cellForRowAtIndexPath:.

Read Apple's documentation, like Objective-C: A Primer. It's explained right there. You know, the maker (Apple or Microsoft) has a lot of documentation on their site ...

Objective-C uses named, inline parameters for methods. (As bblum points out in the comment below, this style of parameters are sometimes called "interleaved".) This is a reflection of it's heratage as a mix of C and SmallTalk syntax. The trailing colons denote the names of the parameters to the method. For your method, the full name of the method is referred to as tableView:cellForRowAtIndexPath:. It takes two parameters, a pointer to a UITableView, and pointer to a NSIndexPath. In a java-like language, this method signature would look something like:
public UITableViewCell cellInTableViewForRowAtIndexPath(UITableView tableView, NSIndexPath indexPath);

Every foo:(bar)baz defines a parameter, for example
- (id)initWithTitle:(NSString *)title
message:(NSString *)message
delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ... {
defines a method with five* parameters.
The stuff before the : is part of the name of the method. In this example, the method's name is
initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:
The stuff between the (…) is the type of that argument. Here, we see that the first argument must be an NSString*.
Finally it's the name of the parameter.
(*: Sometimes there is sometimes a , ..., like in here, indicating it's a variadic method.)
The method is called in the syntax
id result = [theAllocedAlertView initWithTitle:#"title"
message:#"message"
delegate:someDelegate
cancelButtonTitle:#"cancel button title"
otherButtonTitles:#"other", #"button", #"titles", nil];
So the name of the method is repeated (in order!), and the parameter names are substituted by the actual arguments.
In C#, the corresponding function signature would look like
object InitWithTitleAndMessageAndDelegateAndCancelButtonTitleAndOtherButtonTitles(
string title,
string message,
object delegate,
string cancelButtonTitle,
params string[] otherButtonTitles);
and called like
object result = theAllocedAlertView.InitWithBlahBlahBlahAndOtherButtonTitles(
"title",
"message",
someDelegate,
"cancel button title",
"other", "button", "titles");

The method selector is:
tableView:cellForRowAtIndexPath:
where each value after the colon is a parameter. The signature is meant to read like an English sentence, i.e. "The TableView's cell for a row at this index".

If this were written in another language it might look like this
// #param (UITableView *) tableView
// #param (NSIndexPath*)indexPath
// #return UITableViewCell
- (UITableViewCell *) someFunctionName(tableView, indexPath) {
}
Thats roughly speaking of course. It would not be written like this in objective-c. However I believe it is possible to write a good chunk of your program in c++

Related

Why use Message Forwarding

Why would you use Message Forwarding in Objective-c. Also when using it, you need to call the Surragate method with performSelector? I am thinking you have a lot of knowledge when you are coding this, why would you need Message Forwarding. I am reading that this is Obj-c multiple inheritance - but I don't see it like this, it is just another object attached to an object.
Hope you know and have a pratical example
Thanks
See my discussion at the end of this section: http://www.apeth.com/iOSBook/ch25.html#_uitabbar
Here I have interposed my own object as the data source for one of Apple's table views. I don't know how the table view works (it's Apple's) and I don't know what their data source does (it's Apple's). So I substitute my own data source but I keep Apple's, and any messages that I don't handle that arrive at my data source are passed on to Apple's. Thus in a sense I have made my data source "inherit" from Apple's.
#implementation MyDataSource
- (id)forwardingTargetForSelector:(SEL)aSelector {
if ([self.originalDataSource respondsToSelector: aSelector])
return self.originalDataSource;
return [super forwardingTargetForSelector:aSelector];
}
- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)sec {
// this is just to quiet the compiler
return [self.originalDataSource tableView:tv numberOfRowsInSection:sec];
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)ip {
// this is why we are here: my tweaks
UITableViewCell* cell = [self.originalDataSource tableView:tv cellForRowAtIndexPath:ip];
cell.textLabel.font = [UIFont fontWithName:#"GillSans-Bold" size:14];
return cell;
}
#end

populating a tableview confusion

Using cocoa on mac osx 10.7 I populated a TableView with some rows, I have some confusions,
names is an NSArray* containing NSString*
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex;
{
return [names objectAtIndex:rowIndex];
}
I checked the protocol reference for the datasource in the apple's documentation
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Protocols/NSTableDataSource_Protocol/Reference/Reference.html
I am returning an NSString* in the above function, the signature of the method only returns id and not NSString* . The documentation gave me no clue about the return type it just says
An item in the data source in the specified tableColumn of the view.
My case was simple NSString* made sense and it worked but I am not sure. I am wondering where is this implicit knowledge coming from as to what type of data has to be returned by this method given there is no mention in the signature and nothing in the method's documentation :/
Any advise ? I am coming from .Net/android/ background the documentations there made more sense probably because those are strongly typed lanuguages ,...
The type of object that you should return is based on how the cells in your NSTableView are defined. By default when you create an NSTableView in Interface Builder, the cells are defined as NSTextFieldCell, so can return an NSString for those cells. However you can define the cells to accept other types of objects in your code (for example NSImageCell, NSButtonCell, etc).

What (void(^)(NSString *)) as method parameter means in Objective-C?

I have to use some private API of my employer and i've got method like this:
- (void)login:(NSString *)username password:(NSString *)password delegate:(void(^)(NSString *))delegate;
What (void(^)(NSString *))delegate means?
This is parameter but i don't know what must be here.
This is a block pointer. If you are unfamiliar with blocks, this basically lets you assign an annonymous function inline as a parameter. The signature here says that the block takes an NSString as a parameter, and returns nothing. You would use it like this:
- (void)login:(NSString *)username password:(NSString *)password delegate:(void(^)(NSString *))delegate;
[someReceiver login:yourUsername password:yourPassword delegate:^(NSString *aString)
{
// This is the block (annonymous function). Do something with the aString paramter
}];
It denotes a block - it's essentially a closure (lambda function, whatever you call it) - Apple's addition to the C language. In this case, it returns void and accepts an NSString object as its only argument.

How to pass data (arrays) between functions

I must use s7graphview library for draw simple histogram, and I've got custom function called
-(IBAction)histogram:(id)sender;. in this function every pixel from image is passed to array as RGB representation. then pixels are counted and I've got red, green and blue array. I can send to NSLog or something but problem is, when I try to send 3 arrays to - (NSArray *)graphView:(S7GraphView *)graphView yValuesForPlot:(NSUInteger)plotIndex;. both functions are in the same .m file, and I have no idea how to pass data between them, because when I write redArray, Xcode don't suggest me this name.
Since - (NSArray *)graphView:(S7GraphView *)graphView yValuesForPlot:(NSUInteger)plotIndex is a delegate method, it should be implemented in your class that is posing as a delegate to S7GraphView object. You don't call explicitly, you define it as such in your .m implementation:
- (NSArray *)graphView:(S7GraphView *)graphView yValuesForPlot:(NSUInteger)plotIndex
{
if ( plotIndex == <some index value> )
return redArray;
else
return nil;
}
I have no idea what plotIndex corresponds with your various color arrays, but you should get the idea.
When the S7GraphView object needs that data, it will invoke that delegate method.
This is not unlike implementing UITableViewDelegate and UITableViewDataSource methods. When a UITableView method -reloadData is invoked, it will call upon your view controller (presuming it is delegate/data source of the table) to supply UITableViewCell objects via
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = <... dequeue or created ... >.
/*
do some cell set up code based on indexPath.section and indexPath.row
*/
return cell;
}
Similar with S7GraphView I'm sure (I don't have the API to see all it does). In your IBAction method, you will probably be doing something like:
- (IBAction)histogram:(id)sender
{
// maybe you recalculate your red, green, and blue component arrays here and cache
// or maybe you calculate them when requested by the delegate method
// tell the S7GraphView it needs to update
// (not sure what the reload method is actually called)
[self.myS7GraphView reloadGraph];
}

Method Syntax in Objective-C

Can someone explain this method declaration syntax for me? In this function, the number of rows of a UIPickerView (slot machine UI on the iPhone) is being returned. From my understanding, the Method is called 'pickerView', and returns an NSInteger.
It passes in a pointer to the UIPickerview called 'pickerView' ... first, why is the method called the same name as the parameter?
Next there is NSInteger parameter called component that tells us which component we are counting the rows for. The logic to decide which is in the body of the method.
What is 'numberOfRowsInComponent? It seems to describe the value we are returning, but it is in the middle of the parameters.
- (NSInteger) pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
if (component == kStateComponent)
return [self.states count];
return[self.zips count];
}
Objective-C methods are designed to be self documenting, and they borrow from the rich tradition of Smalltalk.
I'll try to explain what you have here, -(NSInteger) pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component.
- (NSInteger)
This first portion indicates that this is an Objective C instance method that returns a NSInteger object. the - (dash) indicates that this is an instance method, where a + would indicate that this is a class method. The first value in parenthesis is the return type of the method.
pickerView:
This portion is a part of the message name. The full message name in this case is pickerView:numberOfRowsInComponent:. The Objective-C runtime takes this method information and sends it to the indicated receiver. In pure C, this would look like
NSInteger pickerView(UIPickerView* pickerView, NSInteger component). However, since this is Objective-C, additional information is packed into the message name.
(UIPickerView*)pickerView
This portion is part of the input. The input here is of type UIPickerView* and has a local variable name of pickerView.
numberOfRowsInComponent:
This portion is the second part of the message name. As you can see here, message names are split up to help indicate what information you are passing to the receiver. Thus, if I were to message an object myObject with the variables foo and bar, I would type:
[myObject pickerView:foo numberOfRowsInComponent:bar];
as opposed to C++ style:
myObject.pickerView(foo, bar);.
(NSInteger)component
This is the last portion of the input. the input here is of type NSInteger and has a local variable name of component.
In Objective-C, the name of a method is composed of all of the portions of the declaration that are not arguments and types. This method's name would therefore be:
pickerView:numberOfRowsInComponent:
The method would be equivalent to a C-style function that looked as follows:
edit: (with thanks to Jarret Hardie):
NSInteger pickerViewNumberOfRowsInComponent(UIPickerView * pickerView, NSInteger component)
Adding to the previous answers, I'd just like to say that Objective-C methods (or messages if you prefer) have external and internal parameter names.
So in this case:
- (NSInteger) pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
numberOfRowsInComponent is the external name, the one that you would use when calling this method from the outside.
And component is the internal name of the parameter, the one you use to refer to the parameter from inside of the method.
Hope that clears it up a bit.
It seems to me that Objective-C method signatures are more like sentences. Each parameter deserves a part in method's name. For instance, in C we could have a method (setPersonData) for setting some information about person:
void setPersonData( char* name, int age, float height ) {
and in Objective-C the method would be more descriptive (setPersonName:andAge:andHeight:), like
- (void) setPersonName: (char *)name andAge:(int)age andHeight:(float)height {