Struggling to make sense of some Objective-C code - objective-c

I'm an Objective-C newbie and am enjoying reading/learning Objective-C in order to do iPhone development but I'm struggling to understand some of the code, especially the code that comes with the UIKit framework.
For example, take this line:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSelection:(NSInteger)section {
...
I understand the parameters passed in but am struggling to understand the return parameter. Any help appreciated.

For this particular method, the return type is NSInteger; it is located at the beginning of the method's declaration. See the Objective-C Programming Guide for details on how to declare methods.
The value returned is the number of rows for the given section in a grouped UITableView.

In a more C-like pseudo code this could be rewritten as:
NSInteger returnNumberOfRowsInTableViewSelection(UITableView* tableView, NSInteger section)
{
...
}
Contrast with a similar function using simple types:
int add(int a, int b)
NSInteger is the return type, tableView and section are the parameters. You may find the named parameter syntax in ObjC longwinded and confusing at first but in my opinion it leads to much more readable and maintainable code :)

Related

Passing struct literal to ObjC method

During a talk at the #Scale 2014 conference (around 32:30), Facebook presented their implementation of a declarative UI approach. The slides for a more detailed version of the talk can be found here.
Basically they presented a function call like this (I made my own simplified example from the example in the talk):
[CPInsetComponent
newWithStyle:{
.margin = 15
}
];
My question is: Is this valid ObjC code? I tried to implement this myself
typedef struct {
uint margin;
} CPInsetComponentStyle;
#interface CPInsetComponent : NSObject
+ (SomeOtherStruct) newWithStyle:(CPInsetComponentStyle)style;
#end
but I still get an "expected expression" error on the newWithStyle:{ line. Could you give me a hint how the method declaration would look like?
No, that's not valid Objective-C code. A C99 compound literal of struct type looks like this:
(TheStructType) { .field1 = initializer1, .field2 = initializer2 }
where the field designators are optional.
I can imagine that the code they were presenting was actually Objective-C++. In C++11, the compiler can insert implicit calls to constructors taking an initializer list if certain conditions are met; hence, often you can pass just an initializer list to a function.
The compiler probably doesn't know if your literal struct declaration is of the correct type. For compound literals you need to provide the type in parenthesis followed by a brace-enclosed list of initializers.
[CPInsetComponent newWithStyle:(CPInsetComponentStyle){
.margin = 15
}];

Could someone explain to me the reason for parentheses on types in Objective-C methods?

I am still learning Objective-C but I like to know the "why" behind everything I learn.
I would like to know why an Objective-C method requires that the types are enclosed in parentheses, such as:
- (IBAction) myAction: (UIButton *) sender;
Instead of:
- IBAction myAction: UIButton *sender;
I've tried finding answers and thought about it quite a bit but can't seem to see what the reasoning is for.
What troubles me is sometimes I actually forget that the asterisk (*) needs to be inside the parentheses, sometimes I accidentally type the following incorrect signature:
- (IBAction) myAction: (UIButton) *sender;
As to me, this more logically represents the argument is a pointer, not the type.
That's C casting syntax:
int foo = (int)bar;
Think of it as casting the parameters and return value to specific types.
In the very early days of Objective-C return values and parameters defaulted to the id type. So you'd see method declarations like this:
-myAction:sender;
For numerous reasons it became preferable to strongly type the return value and parameters in Objective-C code, to the point that all return values and parameters are strongly typed, even if they're id:
- (IBAction)myAction:(id)sender;
The asterisk is also C syntax. UIButton* is a specific type, different from UIButton and UIButton**. You could do this:
typedef UIButton* UIButtonRef;
and then use UIButtonRef instead of UIButton*:
- (IBAction)myAction:(UIButtonRef)sender;

Why is it a pointer? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
objective c difference between id and void *
why most of the objects we create in iphone are pointers
According to Stanford university course, 2010/2011
Lecture 3
The guy made something strange there (at least for me), which is that
NSString *digit = sender.titlelabel.text;
Why is digit a pointer?
The type of your digit is id, which is just basically just a C pointer to a certain struct. All references to objects in Objective-C have this primitive type, regardless of the Class of the object. So the answer to your question is, unfortunately, because that's the way Objective-C works.
So whether you're declaring an NSString*, or an UITableViewController*, or MyClass*, your variable has type id. This is the primary means by which the language implements polymorphism. So, for example, the following declarations are equivalent:
NSString *digit;
id digit;
And it's true of method prototypes as well. These are equivalent:
-(UITableViewCell *)tableView:(UITableView)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(id)tableView:(id)tableView cellForRowAtIndexPath:(id)indexPath;
A variable of type id is not an object itself, it is a pointer to an object. It is the handle with which you manipulate an object. Objective-C does all of the class compatibility work at runtime.
Hope this helps. Any questions?
Updates
That's right: int, float, double, char, void, and the pointer combinations, are all C primitive types. You can and will still use these quite a bit, and they are just what they are in a C program. But Objective-C adds the id type as a way to bridge the gap between the primitive typing of C and the very high-level typing of objects by the Objective-C system. id itself is typedef'd as a pointer to a simple struct in objc.h. At the level of the compiler and the language itself, there really isn't too much meaning to the type. For example, you'll almost never declare an array of ids, certainly never perform any arithmetic with them.
In fact, it's not too far a stretch to say that Objective-C is just plain vanilla C with some added syntax (particularly, the square-bracket notation for method invocation), a few extra primitive types (id, IMP, SEL), and a big runtime library. It's this runtime library that handles all things Object-Oriented.
Anyway, to answer your question, when you're actually programming, you will most often (99% of the time) just use class names to declare your variables - NSString *, NSData *, UITableViewController *, and so on. And the compiler will know what you're talking about, and issue a warning if you write code that clearly tries to put an NSString* where an NSData* is expected. But the actual meaning of those types really exists only at runtime.
I've digressed a little, but I'm not sure where your understanding is failing you, so I thought I'd just explain things a bit. You might want to read Apple's The Objective-C Programming Language to get a feel for the language.
NSString is an Objective-C class and all object references in Objective-C are pointers. I would suggest reading through some of the documentation such as Learning Objective-C A Primer:
Notice the * in the first declaration. In Objective-C, object
references are pointers. If this doesn’t make complete sense to you,
don’t worry—you don’t have to be an expert with pointers to be able to
start programming with Objective-C. You just have to remember to put
the * in front of the variable names for strongly-typed object
declarations. The id type implies a pointer.
It's not a digit, it's the "text" from the label, which is (I'm guessing) a string of integers and such to express the time.
So, all NSString types are declared as pointers in Obj-c.
sender.titlelabel.text;
Returns a NSString *
Remember, it's the same as:
NSString *str = [sender.titlelabel getText];
Because text is too. Or more preceisly, because the getText message returns a pointer.
You can find an intersting about why it has to be a pointer:
NSString and Pointers
I Hope it will help you to understand it in a Objective-C way.

Simple inline function call equivalent in Objective-C - how?

I've been learning Obj-C since getting a MBP about a month ago. I'm fairly comfortable with what I'm learning & things are slotting in to my rusty old brain pretty well. Except there's one thing I'm just not sure if I'm overlooking, or if just going over my head, or I'm looking for something that isn't there.
Most languages I've used have a way of slotting in an inline function call to simplify the coding, & I'm just not sure how this translates in Obj-C. Especially I'm referring to when the function being called is in a separate file, for the coding purposes of keeping similar functions together.
So far, the only way I've seen in Obj-C guides & tutorials is to create a class with methods & then instantiate that class (within the class you're working) to access the method in a [message]. Is this the way it's done in Obj-C? The only way? The best way for some reason? I know classes have their place in many languages & I use them myself, but I'm referring to simple little inline function calls where I usually wouldn't go to the trouble of creating a complete class.
To use a simple C++ console example of my point (only showing the .cpp files):
// example mainFile.cpp
#include <iostream>
#include "mainFile.h"
#include "functionsFile.h"
using namespace std;
void theMainFunction () {
int resultBeforeAltering = 100;
// alterTheResult() = simple inline function call I'm referring to
cout << "The result is " << alterTheResult(resultBeforeAltering);
}
.
// example functionsFile.cpp - could contain many similar functions
#include "functionsFile.h"
int alterTheResult (int resultToAlter) {
int alteredResult;
if (resultToAlter < 100) {
alteredResult = resultToAlter * 2;
} else {
alteredResult = resultToAlter * 3;
}
return (alteredResult);
}
Is there an equivalent approach to do alterTheResult() in Obj-C (assuming mainFunction() was an Obj-C method)?
I've seen reference to functions within Obj-C, but they seem to be C functions being referred to. C functions are not what I'm asking about here.
Thanks in advance, answers much appreciated.
Yes, the way to inline is to use C or C++ inlining -- that's perfectly legal (for C++, that will require compiling as ObjC++). An ObjC method will never be inlined (until LLVM produces a JIT compiler =p).
If you simply want to organize methods in another file, you may want to try an ObjC category:
// NSString_MONStuff.h
#interface NSString (MONStuff)
- (BOOL)mon_isPalindrome;
#end
// NSString_MONStuff.m
#implementation NSString (MONStuff)
- (BOOL)mon_isPalindrome { return ...; }
#end
Again, those will not be inlined.
You can also use C or C++ external functions or classes instead of categories for organization - the benefit is speed, size, reduced dependencies, and safety. The choice is yours, but there's no way to inline an objc method (it's a very dynamic langauge).

Can someone explain function names in Objective-C? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Method Syntax in Objective C
So I totally get the more common functions like:
-(void)viewDidUnload{
self.controllers = nil;
[super viewDidUnload];
}
However coming from a different programming background, I sometimes struggle with something like:
-(NSInteger) tableView: (UITableView *)tableView
numberOfRowsInSection:(NSInteger)section{
return [self.controllers count];
}
So I know the function returns a NSInteger. However I do get a little confused in how to mentally organize the rest of the function name ETC. I need to be able to visualize some structure. Like in this case is the function name numberOfRowsInSection with the parameter called section?
Help in this matter would be appreciated.
You can think of it like other programming languages by looking at
[object action:var withFoo:baz]
as
object."action:withFoo:"(var, baz)
Everything before colons is part of the method name, and everything after is arguments, so the name of the method is interleaved with the arguments passed to the method.
Yes, the way that Objective-C mixes arguments with parts of the method name seems weird at first. Everyone goes through a short adjustment period in this respect. But give it time -- after a little while, you may not want to ever see a comma-separated, parenthesized list of nameless parameters ever again.
In C++, you'd say something like:
Color *color = new Color(0.5, 0.7, 0.2, 0.8);
You know what those values mean, right? There's four of them, so obviously the parameters are in red, green, blue, alpha order. Or was it alpha, red, green, blue? Of course, it could also be hue, saturation, value, alpha... well, it doesn't really matter because you can always just look it up.
In Objective-C, you say:
UIColor *color = [[UIColor alloc] initWithRed:0.5 green:0.7 blue:0.2 alpha:0.8];
Isn't that better? You'll definitely still need to consult the documentation from time to time to remind yourself exactly what a method does, or what methods a class makes available. But you won't often find yourself consulting the docs just to figure out which parameter goes where.
Objective C has a descriptive way of writing methods..
-(NSInteger) tableView: (UITableView *)tableView numberOfRowsInSection:(NSInteger)section{}
It is a methods tableView, returning an NSInteger , takes two argument - a UITableView reference and an integer section. Now consider numberofRowsInSection as a description of what the argument is all about.Look at this example
-(NSInteger) calculateSum:(NSInteger)operand1 secondOperand:(NSInteger)operand2 andThirdOperand:(NSInteger)operand3{}
and I can call this methods as
[self calculateSum:var1 secondOperand:var2 andThirdOperand:var3];
Here "secondOperand" and "andThirdOperand" are not essential, I can write the above method as
-(NSInteger) calculateSum:(NSInteger)operand1 :(NSInteger)operand2 :(NSInteger)operand3{}
and call this method as
[self calculateSum:var1 :var2 :var3];
But first one is easy to read, if you tell what each variable is ..Hope this helps
Also see I used the word method instead of functions which is normally the objective c way..
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
This is a method that accepts 2 arguments, a UITableView and an NSInteger. It's notated like this: -tableView:numberOfRowsInSection:.
Yep that's basically it. In obj-C the full method names include the arg names. I believe that convention originated from Smalltalk.