Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Core Data Fetching Data Part 2 Semantic error

After doing the core data videos again I am getting a semantic error in the code that also appears in the sample code for Puns in ListViewController.m

case NSFetchedResultsChangeUpdate: [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; <----- /Puns/Puns/ListViewController.m:194:33: Incompatible pointer types sending 'UITableViewCell *' to parameter of type 'PunsTableViewCell *'

that leads to the code here

  • (void)configureCell:(PunsTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath; <------ which has the alert /Puns/Puns/ListViewController.m:15:44: Passing argument to parameter 'cell' here

What causes this error and how can I fix it?

Thanks

2 Answers

The warning the compiler's giving you: ** Incompatible pointer types sending 'UITableViewCell ' to parameter of type 'PunsTableViewCell *'*

Let's abstract that and talk about this warning more generically:

** Incompatible pointer types sending 'A ' to parameter of type 'B *'*

So, you have a pointer type A (you're passing an object of type A) to a method as a parameter that expects a type B.

Now, the way Amit has set the code up A is a parent class to B, that is B is a subclass of A. Because of the way that subclasses work, an object of type B is ALSO of type A.

All of the cells managed by the UITableView are B instances, so when you access a cell through the UITableView by calling

-(A*)cellForRowAtIndexPath:

You KNOW the object being returned is of type B, but the above method returns an object of type A. You then take the return value and hand it off immediately to the

- (void)configureCell:(B *)cell atIndexPath:(NSIndexPath *)indexPath

method. Since this method expects a B and you're passing it an A the compiler warns you. It happens to work out in this case because the A you're passing HAPPENS to be a B. This wouldn't be the case if, for example, your UITableView had additional cells that weren't of type B. In that case it would be possible that you'd be passing another object of type C.

To fix this issue, you can cast the A object to a B object. This would look like:

(B*)someObjectOfTypeA;

Doing this will shut the compiler up. But how would this work in the specific case you asked about?

Replace B with PunsTableViewCell and A with UITableViewCell.

(PunsTableViewCell*)cellOfTypeA;

[self configureCell:(PunsTableViewCell*)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];

Hope this makes sense.

Thanks Aaron, yes it makes sense. I think A and B collided in my brain, but I will get the hang of it :o)