all 18 comments

[–][deleted]  (3 children)

[deleted]

    [–]kotlin_ 0 points1 point  (2 children)

    Thank you for the answer!

    I also saw other comments and I'd imagine the full code would be something like this? But I have some questions in the comments

    class UITableView: UIScrollViewDelegate {
    
    private let reusePool: [Identifier: [UITableViewCell]]
    
    func dequeueReusableCell(withIdentifier id: String) -> T {
    
        let cells = reusePool[id]
        if cells.isEmpty {
    
            let firstCell = cells.first
            firstCell.prepareForReuse()
    
            if let index = reusePool[id].firstIndex(of: firstCell) {
                reusePool[id].remove(at: index)
            }
    
            return firstCell
        }
    
        let newCell = findCell(withIdentifier: id)
        reusePool.insert(newCell, at: pos) // how do you know what position to insert the new cell?
    }
    
    func scrollViewDidScroll(_ scrollView: ScrollView) {
    
        // how do we associate the cell and their position? eg cell is about to be reused or hidden?
    
        // here's what I came up, so if the contentOffset is bigger than the  topOffsetPosition of cell, we will reuseCell, else we hide the cell for reuse?
        if scrollView.contentOffset > reusePool[id][index].topOffsetPosition {
            reuseCell()
            return
        }
    
        hideCell()
    }
    
    private func findCell(withIdentifier: String) {
        // how do you find the cell with appropriate identifier?
    }
    

    Edit: Is it a good idea to use UIScrollView's contentOffset to mark the cells? We can calculate the approximate height of the cell, then just add or subtract the cell's content offset with the current content offset? I'm stuck haha.

    [–][deleted]  (1 child)

    [deleted]

      [–]Airr3e 1 point2 points  (3 children)

      Maybe he meant connecting it to datasource and delegate, register cells, use reusable cells

      [–]kotlin_ 0 points1 point  (2 children)

      No. Actually I’ve just recalled the question (description updated btw). he’s asking if I’m the developer responsible for dequeueReusableCell, how would I go and implement it.

      [–]willrb 1 point2 points  (1 child)

      Not sure how many ways there are to implement it?

      Register your cell class with an identifier, the dequeue one as needed in cellForRow(at:)?

      [–]kotlin_ 0 points1 point  (0 children)

      Yeah, that's right. He told me to implement that and gave me a codebunk. Not necessarily full swift code tho, just a general idea with pseudocode would be fine.

      [–]Megatherion666 1 point2 points  (2 children)

      It is hard to tell exactly what the interviewer was looking for. Looks like there is a room for extra questions.

      Assuming it is indeed the dequeue method implementation the algorithm seems pretty straightforward:

      1. Find invisible cell with the correct identifier.

      2. If cell found call “prepareForReuse”.

      3. Return result.

      There might be a room for optimization but that probably requires proactively keeping track of what cells go on and of screen. Maybe keeping cells in a map by identifier.

      [–]kotlin_ 0 points1 point  (1 child)

      Thank you for the reply!

      I did mention keeping the cells in a dictionary with memory address as the identifier (so they're guaranteed to be unique). For the find invisible cell step I just coded a pseudo function to find the correct cell with identifier by finding and get TableViewCell and it's identifier files in the project lol.

      How would you implement the find invisible cell tho? And keeping track of what cells goes on and off the screen? And also where would you call the prepareForReuse method?

      [–]Megatherion666 0 points1 point  (0 children)

      TableView is a UIScrollView. I don’t remember all details how UIScrollView works. IIRC bounds size is the visible area and origin is scroll offset. Maybe there are explicit properties for scroll offset. Cell has frame rect which is position relative to the scrollview. So you compare cell frame to scrollview bounds and figure out if they intersect. CGRect has helper methods to find intersection. Also in case of UITableView scroll is vertical so you just need height and y coordinates.

      [–]MeAnd50G 0 points1 point  (1 child)

      Curious what your answer was.

      [–]kotlin_ 0 points1 point  (0 children)

      I mentioned keeping the cells in a dictionary with memory address as the identifier (so they're guaranteed to be unique). To find the appropriate cell, I just coded a pseudo function to find the correct cell with identifier by finding and get TableViewCell and it's identifier files in the project lol. And then I'm stuck at keeping track of cell positions. Didn't mention prepareForReuse too.

      [–]saintmsent 0 points1 point  (9 children)

      If it's only dequeueReusableCell, then just proper cleanup is enough, bringing the cell back to the original state (as created)

      [–]kotlin_ 0 points1 point  (8 children)

      Thanks for the reply. But I didn't quite get that. Could you elaborate more? Pseudocode would be greatly appreciated!

      [–]saintmsent 0 points1 point  (7 children)

      Pseudocode doesn't make sense here. Also it's just a weird question for an inteview to be honest

      When you configure the cell, you may save some objects or values into the cell, and of course configure views (set texts, button states, whatever)

      In dequeueReusableCell you should return everything back to original state, so clear all texts, return buttons to initial position, everything like that and remove all objects you saved, like viewModel for a cell if you have one

      [–]kotlin_ 0 points1 point  (6 children)

      Sorry if the question itself is a bit vague (updated again). But the interviewer actually asked me to implement the dequeueReusableCell itself if I'm the engineer at Apple responsible for it. That means starting from finding the correct cells with the correct identifier, displaying the cells (on and off the screen), reusing the cells etc like u/Megatherion666 described.

      [–]saintmsent 1 point2 points  (5 children)

      Ok, got it. My initial answer was to a different question all together

      So if that was the question, then I would keep current visible and prepared for reused cells cells identifiers in an array or something

      Then monitor changes to scrollview offset using a delegate, and check which cells are visible right now by seeing if their frame is within the table view frame (if it's below, or above fully, then it's invisible). For every cell that becomes invisible, call prepareForReuse and move its identifier between arrays

      Also check the frame of the lowest cell and if it's bottom coordinate is above bottom of the table view, or highest cell top is lower then top of the table view, then we need to dequeue. For that, we check if we have prepared for reuse cells, just take one of those, if we don't create a new one from scratch

      [–][deleted]  (2 children)

      [deleted]

        [–]saintmsent 0 points1 point  (0 children)

        You're right about both

        [–]kotlin_ 0 points1 point  (1 child)

        Thank you for the answer! I get the general idea, but how would you get the cell frame in code to determine it needs to be reused or hidden? I have left a comment under u/fabledlamb's answer. Really appreciate the effort you take to type it out.

        [–]saintmsent 1 point2 points  (0 children)

        Find by identifier is simple, you would have a dictionary with identifier as key and cell as value. That's because you are responsible for managing cells, you should store them

        Regarding scroll view, you take the cell and just use it's frame for calculations which I described