Objective c 块和变量

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

在我探索blocks Opportunity的那一刻,我读了十多遍苹果(Apple docs),但我无法理解博客示例和代码中的blocks行为。我知道块修改器。因此,请看我的几个例子,并说明它是否有效:

1) 不工作。需要阻止,因为我想修改object.和self-retained(正确吗?),在博客中,我被self的retain循环吓坏了。是吗

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如果我是正确的。这是错误的<代码>此处不需要块
。安德烈亚斯·佐尔曼的答案是正确的。