试图理解iOS上的块

Spa*_*Dog 11 iphone objective-c-blocks

我试图了解如何在iOS上使用块.我读过Apple的文档但是,像往常一样,它们含糊不清,并且没有提到几个重要的信息.我也搜索过没有成功.这就是我想要做的练习,以便理解这一点.

我创建了一个块来读取字符串并将字符串与之前的读取进行比较.如果字符串不相同,则返回YES,如果它们相同,则返回NO.

这就是我做的:

我在.h上宣布这个

BOOL (^differentStrings)(void);
Run Code Online (Sandbox Code Playgroud)

我在.m中声明了这个,在viewController中的viewDidLoad中

__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){

    currentString = [self getString];
    NSLog(@"%@", currentString); // not printing anything on console

    if (![currentString isEqualToString:previousString]) {
        previousString = currentString;
        return YES;
    } else {
        return NO;
    }
};
Run Code Online (Sandbox Code Playgroud)

这就是我的用法:我有一个线程可以做到这一点:

if (differentStrings)
  NSLog (@"strings are different);
Run Code Online (Sandbox Code Playgroud)

这些是我遇到的问题:

  1. 块始终返回YES(字符串不同)
  2. 我不习惯在videDidLoad中声明这个.我该怎么声明这个,所以我可以全局使用它作为方法?我应该像方法那样把它放进去吗?
  3. 我在块中调用方法"getString".可以吗?
  4. 我发现奇怪的是在.m上声明块变量.我认为,我应该在.h上声明块变量,然后在.m上使用它们.我试过这样做,但收到了一个错误.
  5. 我已经在块的第一行设置了一个调试点,但它并没有停在那里;
  6. 块内的NSlog行不打印任何东西.是不是被叫了?

你能帮助我吗?

BJ *_*mer 15

你误解了块是如何工作的.(好吧,这很明显.)与previousString指向NSString的变量相同,differentStrings是指向的变量.不是运行块的结果,而是块本身.也就是说,在你这样做之后:

__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){

    currentString = [self getString];
    NSLog(@"%@", currentString); // not printing anything on console

    if (![currentString isEqualToString:previousString]) {
        previousString = currentString;
        return YES;
    } else {
        return NO;
    }
};
Run Code Online (Sandbox Code Playgroud)

differentStrings是一个指向的变量.因此,当你这样做时:

if (differentStrings)
Run Code Online (Sandbox Code Playgroud)

...你只是检查是否differentStrings包含0或NULL以外的东西.由于它包含一个块,因此它不为空,因此它的计算结果为true.

记住:differentStrings是块变量,而不是BOOL变量.它包含一个块(一个函数,如果你愿意的话),调用它时会返回一个bool.因此,为了实际运行块,您需要调用它.像这样:

differentStrings();
Run Code Online (Sandbox Code Playgroud)

或者,在您的情况下:

if (differentStrings()) {
    NSLog (@"strings are different");
}
Run Code Online (Sandbox Code Playgroud)

编辑:正如注释中所指出的那样,因为它differentStrings是一个实例变量,所以你需要copy它,就像你调用retain分配给实例变量的任何其他对象一样.(由于技术原因,我不会去到现在,你应该总是使用copy与块代替retain).同样,你需要调用release一些点以后,也许在你的dealloc方法.