Fix memory leak by using a dictionary of offscreen cells for height calculations

This method replaces the previous usage of
dequeueReusableCellWithIdentifier: from within
tableView:heightForRowAtIndexPath:, which causes cells to be leaked
because they are never returned from tableView:cellForRowAtIndexPath: