Im writing this on a mobile device so I can’t verify this, but typically the defer block happens upon deallocation. Deallocation happens at the end of the auto release pool.
__block int n = 0;
@autoreleasepool {
id defer = [MyDefer block:^{
n = 10;
}];
}
XCTAssert(n == 10);
Objects get deallocated at the end of an auto release pool so instead of using an implicit one I make it explicit.