- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是 this post 的延续.我的 NSOperation block 有问题,我的应用程序在 completionblock
中崩溃。
我认为问题是一个保留周期(我有一个警告:在此 block 中强烈捕获 self 可能会导致保留周期
),我尝试 this solution (见上面的代码),警告消失了,但应用程序仍然崩溃。
应用程序是一个简单的 tableView。该操作对传递的图像进行一些修改。
这是我第一次自己创建和使用 block ,谢谢你给我一些基本的解释
代码:
TableViewController.m:
在 tableView 中:cellForRowAtIndexPath:
[[ImageManager sharedManager] modifyImage:[UIImage imageNamed:@"anImage.png"] completionBlock:^(UIImage *image, NSError *error) {
[cell.imageView setImage:image];
}];
ImageManager.h:
#import <Foundation/Foundation.h>
@interface ImageManager : NSObject
@property(nonatomic, strong) NSOperationQueue *imageOperationQueu;
-(void) modifyImage:(UIImage*)image completionBlock:(void(^)(UIImage *image,NSError *error)) completBlock;
+ (id) sharedManager;
@end
ImageManager.m:
#import "ImageManager.h"
#import "ImageOperations.h"
static ImageManager *MySharedManager = nil;
@implementation ImageManager
@synthesize imageOperationQueu;
+ (id)sharedManager
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (MySharedManager == nil) MySharedManager = [[self alloc] init];
});
return MySharedManager;
}
- (NSOperationQueue *)imageOperationQueu
{
if (!imageOperationQueu)
{
imageOperationQueu = [[NSOperationQueue alloc] init];
[imageOperationQueu setMaxConcurrentOperationCount:3];
imageOperationQueu.name = @"imageOperationQueu";
}
return imageOperationQueu;
}
-(void) modifyImage:(UIImage*)image completionBlock:(void(^)(UIImage *image,NSError *error)) completBlock
{
ImageOperations *op = [[ImageOperations alloc]initWithImage:image WithCompletionBlock:completBlock];
[self.imageOperationQueu addOperation:op];
}
@end
ImageOperations.h:
#import <Foundation/Foundation.h>
typedef void (^CompletionBlock)(UIImage *image,NSError *error);
@interface ImageOperations : NSOperation
@property(nonatomic, weak) CompletionBlock completBlock;
@property(nonatomic, strong) UIImage *imageToTransform;
-(id)initWithImage:(UIImage *)image WithCompletionBlock:(CompletionBlock) block;
@end
ImageOperations.m:
#import "ImageOperations.h"
@implementation ImageOperations
@synthesize imageToTransform;
@synthesize completBlock;
-(id)initWithImage:(UIImage *)image WithCompletionBlock:(CompletionBlock) block
{
if (self = [super init])
{
NSLog(@"initWithImage");
self.imageToTransform = image;
[self setCompletBlock:block];
}
return self;
}
- (void)main
{
@autoreleasepool
{
UIImage *img = [self setRoundedImage:self.imageToTransform];
__weak ImageOperations *imgOp = self;
[imgOp setCompletionBlock:^{
NSLog(@"setCompletionBlock");
imgOp.completBlock(img,nil);
}];
}
}
-(UIImage*)setRoundedImage:(UIImage*)image
{
// ..
}
@end
最佳答案
几个想法:
您将 block 定义为 weak
属性。在Working With Blocks Programming with Objective-C 指南的部分建议您改用copy
。 (注意,我们复制的是 block ,而不是它使用的对象;不过,您必须注意该 block 内的强引用。) block 变量的范围非常微妙。 (请参阅 Block Programming Topics 指南中的 Patterns to Avoid 以获取示例。)调用因 weak
而发布的 block
可以生成一些不可预测的结果。使用复制
。
您的 tableview 有一个微妙的问题,如果在调用完成 block 时单元格已经滚动,将会发生什么。该单元格可以重新用于表格的另一行。 (事实证明,圆角逻辑可能足够快,这个问题不太可能自己显现出来,但如果您执行较慢的操作(例如下载图像或图像很大),这很关键。)无论如何,而不是:
[[ImageManager sharedManager] modifyImage:[UIImage imageNamed:@"anImage.png"] completionBlock:^(UIImage *image, NSError *error) {
[cell.imageView setImage:image];
}];
您可能想调用 UITableView
方法 cellForRowAtIndexPath
(不要与 UITableViewController
方法 tableView:cellForRowAtIndexPath:
):
[[ImageManager sharedManager] modifyImage:[UIImage imageNamed:@"anImage.png"] completionBlock:^(UIImage *image, NSError *error) {
if (error == nil)
{
UITableViewCell *updateCell = [tableView cellForRowAtIndexPath:indexPath];
// if cell has scrolled off screen, this will be `nil`, so let's check
if (updateCell)
[updateCell.imageView setImage:image];
}
}];
您可能需要注意 imageNamed
方法本身在第一次检索图像时可能很慢的事实。如果所有单元格都返回相同的 imageNamed
,这不是问题,但如果 (a) 使用唯一的 imageNamed
文件; (b) 如果处理较旧、较慢的设备,您甚至可能希望将 imageNamed
进程也插入后台队列。在较新的设备上(或在模拟器上),你永远不会看到这个问题,但如果你在一个旧的、慢速的设备上测试,你可能会看到快速的 tableview 滚动中有些卡顿(但因为 imageNamed
缓存,您只会在首次检索图像时看到这个断断续续的 UI...如果您对所有图像使用相同的图像名称,您可能看不到这一点。)
您对 completBlock
的调用正在后台队列中完成。由于您正在进行 UI 更新,因此您可能希望确保将其分派(dispatch)回主队列:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// call the completBlock here
}];
关于iphone - 将 block 与 NSOperation 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15660684/
我的 blockly.js 文件中有以下代码 Blockly.Blocks['account_number'] = { // Other type. init: function() {
首先抱歉我的英语不好,我正在开发 Image Splitter 应用程序并且已经完成,但是现在的要求是当图像被分割(分成几 block /chunks)那么图像 block 的每一 block (ch
#value: 消息的返回值,当发送到一个 block 时,是该 block 中最后一句话的值。所以 [ 1 + 2. 3 + 4. ] value 计算结果为 7。我发现有时很难使用。有没有办法显式
我想构建一个包含 3 div 的响应式导航栏相同的 width和 height . 我申请了 inline-block到每个 block ,我得到一个我不理解的行为。 问题是,第三 block 由 2
我希望使用 Blockly 来允许非技术人员用户指定测试脚本。 它的一部分需要一个文件选择器,但是,我看不到 Blockly 有一个。是吗? 实际上,我找不到完整的标准 block 列表。谁有网址?
仅当您位于父 block 内部时,父 block 的 props.isSelected 才为 true,但当您在该 block 的 innerBlocks 内进行编辑时则不然。 如何从父 block
仅当您位于父 block 内部时,父 block 的 props.isSelected 才为 true,但当您在该 block 的 innerBlocks 内进行编辑时则不然。 如何从父 block
我想创建一个具有不同背景颜色 block 和不同悬停颜色 block 的导航栏 block 。我可以分别创建不同的悬停颜色 block 或不同的背景颜色 block ,但不能一起创建。所以请告诉我如何
我正在使用看到的代码 here定期执行代码: #define DELAY_IN_MS 1000 __block dispatch_time_t next = dispatch_time(DISPATC
为什么 block 必须被复制而不是保留?两者在引擎盖下有什么区别?在什么情况下不需要复制 block (如果有)? 最佳答案 通常,当您分配一个类的实例时,它会进入堆并一直存在,直到它被释放。但是,
我想弄清楚我这样做是否正确: 如果我有一个 block ,我会这样做: __weak MyClass *weakSelf = self; [self performBlock:^{
我想制作一个 4 block 导航菜单,虽然我已经显示了一个 block ,然后单击打开第二个 block ,从第二个开始选择并再次单击出现第三个 block ,第四个 block 相同...这是我的
例如,这样更好吗? try { synchronized (bean) { // Write something } } catch (Int
我想让一只乌龟检查前方小块的颜色并决定移动到哪里。如果前面的补丁不是白色的,那么乌龟向左或向右旋转并移动。我的 If 决策结构中出现错误,显示“此处应为 TRUE?FALSE,而不是 block 列表
我想创建一个 block 对角矩阵,其中对角 block 重复一定次数,非对角 block 都是零矩阵。例如,假设我们从一个矩阵开始: > diag.matrix [,1] [,2] [
我是区 block 链新手。突然我有一个问题,我们是否可以通过区 block 号来访问以太坊区 block 链上之前的区 block 数据。 例如我创建了一个block1、block2。 block
我是区 block 链新手。突然我有一个问题,我们是否可以通过区 block 号来访问以太坊区 block 链上之前的区 block 数据。 例如我创建了一个block1、block2。 block
我创建了一个等距环境,全部使用 Javascript 和 HTML5 (2D Canvas),大部分情况下工作正常。我面临的问题是使用不同高度的图 block ,然后对图 block 上的对象索引进行
这是令我困惑的代码: public Integer getInteger(BlockingQueue queue) { boolean interrupted = false; try
我有一个基于 TPL 数据流的应用程序,它仅使用批处理 block 和操作 block 就可以正常工作。 我已经添加了一个 TransformBlock 以尝试在发布到批处理 block 之前从源中转
我是一名优秀的程序员,十分优秀!