1

我知道块是 ios 中添加的最新功能之一。但我真的找到了一个

艰难的学习吧。

我见过人们在做以下事情

typedef void(^CallBackBlk) (NSString *);


@property(copy,nonatomic)CallBackBlk block;

在 .m 类中

-(void)doSomething:(CallBackBlk )cb{

       self.block=cb;

}

我从来不明白在这里将它分配给 cb 有什么用。我不能简单地执行以下操作

-(void)doSomthing{

   block(@"my string");

}

我真的没有得到将块存储在实例变量中的目的。有什么帮助吗

我举个例子。任何帮助是极大的赞赏

4

5 回答 5

4

在你的doSomething方法中,block从哪里来?

回答这个问题,你就会有你的理由。


啊——评论把问题说清楚了。Snark 是有目的的(snark 并且懒得在早上 7 点在我的 iPhone 上输入真正的答案 :)。

实例变量只是放置东西的插槽。开始时该插槽中没有任何内容。

在您的情况下,您可以实现:

-(void)doSomething:(CallBackBlk )cb{
       cb();    
}

但是,通常,当您异步执行某些操作时会使用回调。例如,您可能会这样做:

[myObject doSomething:^{
     NSLog(@"did something");
 }];

接着:

-(void)doSomething:(CallBackBlk)cb {
    dispatch_async(... global concurrent queue ..., ^{
         ... do some work ...
         cb();
    });
 }

也就是说,doSomething:一旦dispatch_async()发生就会返回。回调块用于回调,让您知道异步操作已完成。

当然,仍然不需要实例变量。参加那个做一些更进一步的课程;使其成为某种相对复杂的状态转换引擎。比如说,就像您的普通互联网下载器或计算繁重的模拟引擎一样。到那时,将所有后台工作集中到一个方法中会过于复杂,因此,需要推动回调块(可能有多个;进度更新器、完成块和/或错误块,例如)到实例变量中允许类的实现更清晰地沿着功能线细分。

于 2013-04-12T14:19:20.833 回答
1

如果您想稍后调用该块,您可以这样做,在分配它的方法已经返回之后。

例如,考虑一个管理下载的对象。您可能希望在下载完成时调用一个块(例如更新 UI),但您不希望下载方法必须等到这种情况发生(因为它可能需要很长时间)。

于 2013-04-12T14:21:12.720 回答
1

将块存储在实例变量中有什么用

也许以后可以访问它?

于 2013-04-12T14:19:37.850 回答
0

要使用该块,请调用您的doSomething:方法:

CallBackBlk laterBlock = ^(NSString *someString) {
    NSLog(@"This code is called by SomeClass at some future time with the string %@", someString);
};

SomeClass *instance = [[SomeClass alloc] init];
[instance doSomething:laterBlock];

当您编写类的实现代码时,它可能会达到某种条件或完成一个动作,然后调用laterBlock

if (someCondition == YES) {
    self.block("Condition is true");
}
于 2013-04-12T15:42:55.603 回答
0

也许和使用示例会有所帮助..

我发现将其存储为变量的一个用途是,如果您有多个视图都可以访问另一个视图(对我来说,这是下一个视图上的地图)我使用了由前一个视图设置的块(设置默认位置地图,初始化标记等)然后将其传递到下一个视图,它将运行它,设置地图。让块使用前一个视图的局部变量来访问某些属性很方便。这不是唯一的方法,但我发现这是一种很好的干净方式。

这是在 mapview 的 viewDidLoad 中运行的示例

if(setupMap){
    setupMap(mapView);
}

if(gpsUpdate){
    gpsUpdate(mapView);
}

if(addMarker){
    addMarker(mapView);
}

现在,如果分配了这些块(if 语句检查它们是否为 nil),它将运行它们并为地图进行适当的设置。并非每个视图都需要执行这些操作,因此它们只会将需要完成的操作传递给地图视图。这使地图视图保持非常通用的目的,并且代码得到了很多重用。写一次用很多!

于 2013-04-12T14:24:17.793 回答