I prefer to do the checkin, assuming the developer has done the work correctly (ie be optimistic about their code quality)
If it turns out a review requires rework, then the dev can checkin fixes - in many ways this is exactly the approach taken with bugs, commit; build; test; commit fixes. Its not a problem with releases, why should a code review be any different?
I always create a ticket for the review, just like any other task - and track the progress of it, so the dev commits, he creates a new code review task for the commit and assigns it to the reviewer who then uses it to record any review failures that need work - and passes it back to the dev who fixes and re-assigns, or closes it.
The developer should be working on a branch rather than the mainline trunk, you can then perform the review without holding him up - he can continue to work on other tasks, while he waits for you to perform the review.
In the old days I used ReviewBoard for reviews - this requires you to upload a diff (the SCM was automated to provide these and create the review tasks). Now I'd use Redmine which can integrate the review process with the SCM tool and its inbuilt ticket tracker. (you will need the CodeReview plugin though).
In all cases, review after commit - its the only way to keep productivity up.
quick edit: the benefit of post-commit include:
a) if you mark the revision you reviewed, the coder cannot cheat and tweak their code when the commit it after the review...
b) the SCM tool gives you a diff of all the changes made since the last review, making review easier.
c) waiting for the review doesn't block the dev from working.
I would work with branches in this case anyway: dev works on a branch, it gets reviewed and merged onto a 'for testing' branch, is tested and then gets merged onto a 'for release' branch. This way, you can easily see that the process for review is exactly like the process for test so you can manage your entire delivery process the same way.