这是在drawRect:
中NSString *generated = [Entry generateString];
const char *cString = (const char*)[generated UTF8String];
dispatch_queue_t queue = dispatch_queue_create(cString, NULL);*/
dispatch_async(queue, ^{
Media *media = [self.entry.media objectAtIndex:i];
UIImage *image = [media getThumbnail];
dispatch_async(dispatch_get_main_queue(), ^{
int bottom = [JHomeViewCell yOfMessageBottomWithMessageHeight:self.cellInfo.messageHeight
withMonth:self.cellInfo.hasMonth];
CGRect frame = CGRectMake(87 + (68 * i),
bottom,
THUMBNAIL_SIZE.width,
THUMBNAIL_SIZE.height);
[image drawInRect:frame];
});
});
现在,它正在objectAtIndex行崩溃。这不是一个无效的索引。代码在这里工作正常。
编辑:我收到了这个错误:Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'statement is still active'
编辑2:我放入NSLogs,第一个获得media.count。它崩溃了同样的错误。
答案 0 :(得分:6)
这里的问题是你在你应该去的地方以外的地方画画。当您从drawRect:
返回时,您告诉操作系统您已完成。你不能在从drawRect:
返回之前产生一个异步线程,并期望能够通过回到主线程来绘制,因为一旦从drawRect:
返回,上下文就会被破坏。
通常的做法是在单独的线程上缓存信息,然后在需要绘制的区域上调用invalidateRect:
,允许drawRect:
方法除了快速绘制外什么也不做并退出。
如果您想延迟加载缩略图,我建议将缩略图的副本存储在私有位置(可能使用NSCache并使用您的图像标识符作为密钥),然后如果图像存在于缓存中{调用{1}},绘制图像,否则绘制占位符并使用GCD将图像添加到队列以创建缩略图。在该调度队列调用内部:
drawRect:
如果您发现难以计算位置,或者您很快得到缩略图,则可以延迟invalidateRect:并在绘制例程结束时调用最终的dispatch_async(但仅限于用于检索的排队缩略图)。这将导致单个全区域重绘,而不是包含单个缩略图的每个区域的多次重绘。