When to use dequeueReusableCellWithIdentifier vs dequeueReusableCellWithIdentifier forIndexPath
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
These two dequeue APIs reflect two generations of table-view usage in UIKit. In modern iOS code, dequeueReusableCell(withIdentifier:for:) is the standard choice because it guarantees a cell when registration is set up correctly, while the older dequeueReusableCell(withIdentifier:) returns an optional and belongs mostly to legacy patterns.
The older API
The older method is:
This may return nil if no reusable cell exists and no registration or storyboard prototype covers that identifier. Older code often looked like this:
That was normal when cell creation was managed manually.
The modern API
The newer and preferred method is:
This method assumes you have already registered the cell class or nib, or provided a prototype cell in Interface Builder. If registration is correct, the method always returns a cell and does not require a nil check.
Typical setup:
Then in cellForRowAt:
This is cleaner and matches how Apple expects table views to be configured in current UIKit code.
Why the for: version is better
Advantages of dequeueReusableCell(withIdentifier:for:):
- no optional handling in normal use
- cleaner
cellForRowAtimplementation - stronger alignment with registration-based cell setup
- fewer hidden fallback creation paths
If registration is missing, it fails loudly, which is usually better than returning nil and hiding a setup mistake.
When the old method still appears
You still see dequeueReusableCell(withIdentifier:) in:
- older Objective-C and Swift codebases
- highly customized legacy table setup
- code paths outside
cellForRowAtwhere no index path is available
Even then, it is often a signal that the view code predates the more modern registration pattern.
UICollectionView follows the same direction
The same general idea exists for collection views. Modern UIKit encourages registration and index-path-based dequeuing because it makes reuse behavior more explicit and predictable.
That is why, in current code, the question is usually not "which one should I prefer," but "is there a specific legacy reason I still need the old one."
If there is no such reason, the for: variant should usually be your default starting point.
Common Pitfalls
The most common mistake is using dequeueReusableCell(withIdentifier:for:) without registering the cell class, nib, or storyboard prototype first. Another is continuing to use the old optional-returning method in new code simply out of habit from older tutorials. Developers also sometimes create fallback cells manually while also trying to use registration-based reuse, which mixes two patterns unnecessarily. Confusion can also arise when the older method is called outside cellForRowAt, because the lack of an index path changes what the API can guarantee. Finally, people often focus on dequeuing method choice while forgetting the more important requirement: reset reused cell state correctly during configuration.
Summary
- In modern UIKit, prefer
dequeueReusableCell(withIdentifier:for:). - The
for:version assumes proper registration and returns a non-optional cell. - The older
dequeueReusableCell(withIdentifier:)mainly survives in legacy or specialized code. - Registration setup is the key requirement for the newer API to work correctly.
- Use one reuse pattern consistently instead of mixing manual creation with registered dequeuing.
- Focus on correct cell configuration after dequeuing, because reuse bugs often come from stale state rather than the dequeue call itself.

