Dynamic UITableView height with Core Data objects
Asked Answered
M

2

7

I've been trying to solve a mystery the past few days as to why my NSFetchedResultsController with a batch size of 20 would always fault in (that is, load into memory) all my objects immediately when the fetch was finished, causing the request to take ~ 20 seconds.

It turns out that it was because in my heightForRowAtIndexPath, the height was based on the length of an NSString property of each fetched object, and so upon reloading the table, if the table has 2000 rows, then the height is calculated for every row in the beginning, and since I access a text property of the object, it would fault in 2000 objects (in 20 size batches) right in the very beginning, causing it to take forever. (I didn't know row heights were calculated all in the beginning).

So the question is, if I have a fetch results controller with a batch size of 20, but my row heights are based on a text property of the object, which if I try to access would cause the object to not be a fault anymore but actually loaded into memory, what would be a workaround to calculating the height?

What are my options?

Midshipman answered 23/6, 2012 at 15:37 Comment(2)
What happens if you check if the object is a fault, if it is, return an arbitrary size, otherwise get the string and calculate? Does the method get called again when the cell comes in to view? I'm just guessing here. That or implementing a lazy load ( I.e new rows are added as you scroll) seem to be your only options.Copyedit
No heightForRow is only called in the beginning of a reload, and does not get called every time a cell appears (like cellForRow would). That's what I was thinking too, but I don't think it would work..Midshipman
S
2

Interesting question. What I would do to boost performance would be to create a property in your model that store the length for that string text. In this way you don't need to calculate the length for each row on the fly but you have a pre-calculated height.

Myabe there could be other valuable solutions.

Sheet answered 23/6, 2012 at 15:47 Comment(5)
But I'd still need to access that integer property, which would cause the object to not be a fault anymore and loaded into memory..Midshipman
@mohabitar It's not quite true. If you prefetch that property into your fetch request and then you access it, the string text is not loaded in memory until you will demand for it, otherwise the text property will remain as a fault.Sheet
Right, but when I do access the string property, the object which is holding the string is loaded into memory (because it was a fault before, uninstantiated.)Midshipman
@mohabitar You need to calculate that height before you display data on your table view. In a different point in your application lifecycle. For example, when you insert the objects.Sheet
Yes I understand, but I think you're still missing the main point: my fetch batch size is 20. Out of 2000 objects, 1985 of them will be faults, meaning any of their properties are not yet instantiated. In order to calculate the height, I need to know the content of the object's property, and by accessing that property causes the object to no longer be a fault. I guess I can create another fetch request that just fetches the text property with no limit on the batch size..Midshipman
O
-1

Create a static method in your view controller class that is in charge of calculating the said height. All you need to supply this function is an NSString and it should return an easily calculated CGFloat. Use this method for returning the needed height of your elements without instantiating them (all you need here is the meta-data of their text).

Octavia answered 23/6, 2012 at 15:44 Comment(2)
Right, but how would the method know what the NSString is without instantiating the objects? The NSString is a property of the object, and if the object is a fault, calling object.textProperty causes the object to be loaded into memory..Midshipman
This issue is related on your implementation. Maybe a workaround to obtain these strings without constructing instances? It's the chicken and the egg :)Octavia

© 2022 - 2024 — McMap. All rights reserved.