mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-04-24 03:45:58 +08:00
Improvements to thread safety during closely spaced edit events.
This applies primarily when beginUpdates / endUpdates is not used. Due to user interaction-driven edits, like reloads or adding content at the bottom, sometimes this is unavoidable in app design and thus critical. I have a diff in flight to make ASDataController / ASRangeController robust against very aggressive thrash testing, which will be added both to the unit test suite and this new example project.
This commit is contained in:
@@ -10,6 +10,10 @@
|
||||
|
||||
#import "ASTableView.h"
|
||||
|
||||
#define NumberOfSections 10
|
||||
#define NumberOfRowsPerSection 20
|
||||
#define NumberOfReloadIterations 50
|
||||
|
||||
@interface ASTestTableView : ASTableView
|
||||
@property (atomic, copy) void (^willDeallocBlock)(ASTableView *tableView);
|
||||
@end
|
||||
@@ -52,6 +56,32 @@
|
||||
|
||||
@end
|
||||
|
||||
@interface ASTableViewFilledDataSource : NSObject <ASTableViewDataSource, ASTableViewDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASTableViewFilledDataSource
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return NumberOfSections;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return NumberOfRowsPerSection;
|
||||
}
|
||||
|
||||
- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ASTextCellNode *textCellNode = [ASTextCellNode new];
|
||||
textCellNode.text = indexPath.description;
|
||||
|
||||
return textCellNode;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface ASTableViewTests : XCTestCase
|
||||
@end
|
||||
|
||||
@@ -60,27 +90,60 @@
|
||||
- (void)DISABLED_testTableViewDoesNotRetainItselfAndDelegate
|
||||
{
|
||||
ASTestTableView *tableView = [[ASTestTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
|
||||
|
||||
|
||||
__block BOOL tableViewDidDealloc = NO;
|
||||
tableView.willDeallocBlock = ^(ASTableView *v){
|
||||
tableViewDidDealloc = YES;
|
||||
};
|
||||
|
||||
|
||||
ASTableViewTestDelegate *delegate = [[ASTableViewTestDelegate alloc] init];
|
||||
|
||||
|
||||
__block BOOL delegateDidDealloc = NO;
|
||||
delegate.willDeallocBlock = ^(ASTableViewTestDelegate *d){
|
||||
delegateDidDealloc = YES;
|
||||
};
|
||||
|
||||
|
||||
tableView.asyncDataSource = delegate;
|
||||
tableView.asyncDelegate = delegate;
|
||||
|
||||
|
||||
[delegate release];
|
||||
XCTAssertTrue(delegateDidDealloc, @"unexpected delegate lifetime:%@", delegate);
|
||||
|
||||
|
||||
XCTAssertNoThrow([tableView release], @"unexpected exception when deallocating table view:%@", tableView);
|
||||
XCTAssertTrue(tableViewDidDealloc, @"unexpected table view lifetime:%@", tableView);
|
||||
}
|
||||
|
||||
- (void)testReloadData
|
||||
{
|
||||
// Keep the viewport moderately sized so that new cells are loaded on scrolling
|
||||
ASTableView *tableView = [[ASTableView alloc] initWithFrame:CGRectMake(0, 0, 100, 500)
|
||||
style:UITableViewStylePlain
|
||||
asyncDataFetching:YES];
|
||||
|
||||
ASTableViewFilledDataSource *dataSource = [ASTableViewFilledDataSource new];
|
||||
|
||||
tableView.asyncDelegate = dataSource;
|
||||
tableView.asyncDataSource = dataSource;
|
||||
|
||||
[tableView reloadData];
|
||||
|
||||
[tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1,2)] withRowAnimation:UITableViewRowAnimationNone];
|
||||
|
||||
// FIXME: Early return because we can't currently pass this test :). Diff is in progress to resolve.
|
||||
return;
|
||||
|
||||
for (int i = 0; i < NumberOfReloadIterations; ++i) {
|
||||
NSInteger randA = arc4random_uniform(NumberOfSections - 1);
|
||||
NSInteger randB = arc4random_uniform(NumberOfSections - 1);
|
||||
|
||||
[tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(MIN(randA, randB), MAX(randA, randB) - MIN(randA, randB))] withRowAnimation:UITableViewRowAnimationNone];
|
||||
|
||||
BOOL animated = (arc4random_uniform(1) == 0 ? YES : NO);
|
||||
|
||||
[tableView setContentOffset:CGPointMake(0, arc4random_uniform(tableView.contentSize.height - tableView.bounds.size.height)) animated:animated];
|
||||
|
||||
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user