Objective c 块和变量
在我探索blocks Opportunity的那一刻,我读了十多遍苹果(Apple docs),但我无法理解博客示例和代码中的blocks行为。我知道块修改器。因此,请看我的几个例子,并说明它是否有效: 1) 不工作。需要阻止,因为我想修改object.和self-retained(正确吗?),在博客中,我被self的retain循环吓坏了。是吗Objective c 块和变量,objective-c,objective-c-blocks,Objective C,Objective C Blocks,在我探索blocks Opportunity的那一刻,我读了十多遍苹果(Apple docs),但我无法理解博客示例和代码中的blocks行为。我知道块修改器。因此,请看我的几个例子,并说明它是否有效: 1) 不工作。需要阻止,因为我想修改object.和self-retained(正确吗?),在博客中,我被self的retain循环吓坏了。是吗 NSDictionary *result = nil; dispatch_async(queue, ^{ result = [self sen
NSDictionary *result = nil;
dispatch_async(queue, ^{
result = [self sendRequest:apiRequest];
});
2) 不工作。我不理解dispatch_async(dispatch_get_main_queue(),^{})的可变范围;。它是否在主线程中看到所有局部变量,或者它是与主线程分离的块,但在主线程中退出?类似于dispatch\u async(dispatch\u get\u main\u queue()^{});复制dispatch_async(队列,^{})中的所有局部变量;并将信号量切换到主线程
NSDictionary *result = nil;
dispatch_async(queue, ^{
NSDictionary *data = [self sendRequest:apiRequest];
dispatch_async(dispatch_get_main_queue(), ^{
result=[data retain];
});
});
3) 博客和斯坦福课程中的例子让我特别困惑,因为它们很有效
- (void)viewWillAppear:(BOOL)animated
{
dispatch_queue_t downloadQueue = dispatch_queue_create(“image downloader”, NULL);
dispatch_async(downloadQueue, ^{
NSData *imageData = [NSData dataWithContentsOfURL:networkURL];
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:imageData];
self.imageView.image = image;
self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
 self.scrollView.contentSize = image.size;
});
});
dispatch_release(downloadQueue);
}
我不明白,因为首先,他们在文章和课程中没有提到self的_块,其次,这段代码修改了变量,但通过属性和编译器并没有发誓变量是不可赋值的,属性改变了引用,而不是值。最后,它起作用了。提前谢谢。1)是的,您需要申报:
__block NSDictionary *results = nil;
如果您使用的是ARC,它应该自动保留和释放结果对象。如果不使用ARC,则首先执行保留
,最后执行释放
2) 块应具有其父范围可用的所有变量/对象的可见性。因此,在一个方法中,您应该能够看到该方法的所有局部变量以及该方法所属的对象(如self
)
3) 我对这个不太确定。一旦离开函数/方法,变量确实会消失(这将是因为大多数块都被调用了,而不是完成了执行),而属于
self
的任何部分都不会消失。也许这与此有关。老问题,但我觉得新读者可能会受益于比现在更准确的答案:
1) result
是指向对象的指针,而不是对象本身。有必要预先结束\u块
,因为该指针被分配到块内。修改块外指针变量指向的对象不是问题,例如
NSMutableDictionary* result = [NSMutableDictionary new];
然后通过[result setObject…]
修改块内的对象就可以了。这就是3)起作用的原因:只有self
指向的对象的变量被修改。指针self
从未分配给
关于块所参照对象的弧下保留,请参见,例如:
谢谢,但是为什么
self.imageView.image=image代码>在第三个示例中工作,但第一个示例中的结果需要\u块?区别是什么?我猜是因为result
在方法完成后(通常可能在块完成之前)将不再存在,您需要告诉它仍然需要它。我猜\u块
保留了它,并表示该块将释放它代码>有效,因为您不直接访问实例变量。它实际上在做[[self-getImageView]setImage]=image代码>如果我是正确的。这是错误的<代码>此处不需要块
。安德烈亚斯·佐尔曼的答案是正确的。