Skip to content

Instantly share code, notes, and snippets.

@n-b
Created January 13, 2014 10:05
Show Gist options
  • Save n-b/8397563 to your computer and use it in GitHub Desktop.
Save n-b/8397563 to your computer and use it in GitHub Desktop.
Demo for a NSAttributedString / HTML parsing issue on iOS 7
@import UIKit;
#pragma mark - Main View Controller
@interface ViewController : UITableViewController
@end
@implementation ViewController
// A simple TableViewController with a large number of cell
//
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 10000; }
// A small HTML fragment is parsed and set as the attributed title for each cell
//
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
NSString * htmlSource = [NSString stringWithFormat:@"<html><p>Row <i>%@</i></p></html>", @(indexPath.row)];
NSAttributedString * attributedText = [[NSAttributedString alloc] initWithData:[htmlSource dataUsingEncoding:NSUTF8StringEncoding]
options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType}
documentAttributes:nil
error:nil];
cell.textLabel.attributedText = attributedText;
return cell;
}
- (void) scrollViewDidScroll:(UIScrollView *)scrollView
{
for (NSIndexPath * indexPath in [self.tableView indexPathsForVisibleRows]) {
[self.tableView cellForRowAtIndexPath:indexPath]; // CRASH
// This crashes as soon as you start scrolling.
//
// [self.tableView visibleCells] doesn't match [self.tableView indexPathsForVisibleRows]
// (There are less cells than there are visible rows.)
//
// This happens because HTML parsing uses Webkit in the main thread, which requires running the main runloop in a common mode.
//
// In other words, -scrollViewDidScroll is called inside -cellForRowAtIndexPath.
}
}
@end
#pragma mark - App Setup
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [ViewController new];
[self.window makeKeyAndVisible];
return YES;
}
@end
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
@n-b
Copy link
Author

n-b commented Jan 13, 2014

Filed as rdar://15803156

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment