3

Hi this is something very simple but is killing me for some reason.

I want to compare the indexPath.row to the total number of rows:

NSInteger *rowCount = (NSInteger *) [self.tableView numberOfRowsInSection:indexPath.section];

if((NSInteger *)indexPath.row < rowCount - 1) {
    //do a
} else {
    //do b
}

but for some reason this isn't working. Is there a correct way of doing this?

Bhavesh Nayi
  • 3,626
  • 1
  • 27
  • 42
Allen
  • 3,601
  • 10
  • 40
  • 59

3 Answers3

4

You don't need any pointers or casts in this code. You're just comparing and storing integer values not objects or anything else. Remember NSInteger is a 'primitive' type not an object.

NSInteger rowCount = [self.tableView numberOfRowsInSection:indexPath.section];

if(indexPath.row < rowCount - 1) {
    //do a
} else {
    //do b
}
Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
  • great thanks! i was overthinking the situation. out of curiousity why doesn't casting work? – Allen Sep 03 '13 at 08:53
  • you didn't mention the specific error and I don't have my complier as I'm answering from my phone. If you search the specific error you may have some luck. Also consider this http://stackoverflow.com/questions/6702161/pointer-comparisons-in-c-are-they-signed-or-unsigned – Carl Veazey Sep 03 '13 at 09:01
  • How can I upvote someone with 8888 rep? Sigh, you got to do what you got to do. – Nikolai Ruhe Sep 03 '13 at 09:22
  • @Nikolai tis an honor – Carl Veazey Sep 03 '13 at 09:28
2

As others have pointed out, you should not cast your integer row counts or indices to pointers to integers.

It's an easy mistake to make, and stems from Objective-C being actual C with a (very rich) layer of cream on top.

Most, if not all, data structures in the Foundation framework are named with an identifier beginning with "NS" (from the old NextStep environment), whether they are objects, plain structs (such as points with x and y) or some primitive types such as integers.

If you are not familiar with C programming it can be difficult to understand the difference, but it really boils down to this:

  • Objects are handled by the runtime engine, a layer of software that takes care of the basic life cycle of your objects by allocating and de-allocating the memory space they need. It uses the part of memory called the heap for that purpose, and in C you can only refer to things on the heap through a pointer. Hence, all Objective-C objects are referred to through a pointer variable: NSString *s = ...

  • Primitive types are handled in Objective-C just as they are in C. You could say that whenever an integer is referred to in an Objective-C program, the compiler really just compiles it as if it were C. And in C, primitive types do not live on the heap (unless you manually allocate and de-allocate memory for them), but either on the stack or, even better (faster), directly in the registers of the CPU. Hence, for all practical purposes, an integer (or float, double, etc.) is always referred to directly, without using a pointer.

The small trouble we have to go through is to understand which of the data types defined in Foundation are primitive types (or structs of primitive types) and which are Objective-C objects. I have found that a simple way to do that is to consult the documentation.

The reason for integers and floating point numbers being implemented as primitive types rather than objects is surely performance considerations and ease of integration with existing C libraries.

PS: I am aware that the above contains a few simplifications - for instance that pointers to primitive types can be used to one's advantage, or that blocks are an example of an Objective-C object allocated on the stack.

Monolo
  • 18,205
  • 17
  • 69
  • 103
  • 1
    Both `numberOfRowsInSection:` and NSIndexPath's `row` and `section` methods return signed integers. – Nikolai Ruhe Sep 03 '13 at 09:30
  • @NikolaiRuhe I guess I should have read [the documentation](https://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewDataSource_Protocol/Reference/Reference.html)... Fixed, thanks! – Monolo Sep 03 '13 at 09:34
0

This will work

int rowCount = [self.tableView numberOfRowsInSection:indexPath.section];

if(indexPath.row < rowCount - 1) {
    //do a
} else {
    //do b
}
Vaibhav Gautam
  • 2,074
  • 17
  • 17