2011-01-06 55 views
11

我想了解如何在iOS上使用块。我已经阅读过苹果公司的文档,但像往常一样,它们含糊不清,并且没有提到几个关键信息。我也搜索了没有成功。这是我正在尝试做的一项练习来理解这一点。试图了解iOS上的块

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

这是我如何做:

我宣布这对.H

BOOL (^differentStrings)(void); 

我在的viewController

__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; 
    } 
}; 

宣布这对.M,里面viewDidLoad中这是怎么了我使用:我有一个线程可以做到这一点:

if (differentStrings) 
    NSLog (@"strings are different); 

这是我的问题:

  1. 块总是返回YES(字符串不同)
  2. 我不舒服,宣布这里面videDidLoad。我应该如何声明这一点,所以我可以在全球范围内使用它作为一种方法?我应该把这个像我会用一种方法吗?
  3. 我在块内调用一个方法“getString”。可以吗?
  4. 我发现奇怪的是在.m上声明块变量。正如我所看到的,我应该在.h上声明块变量,然后在.m上使用它们。我试图做到这一点,但收到了一个错误。
  5. 我已经在块的第一行设置了一个调试点,但它并没有停在那里;
  6. 块内的NSlog行不打印任何东西。是不是被称为块?

你们能帮我解决吗?

回答

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; 
    } 
}; 

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

if (differentStrings) 

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

切记:differentStrings是块变量,而不是BOOL变量。它包含一个块(如果你愿意的话),当调用时会返回一个布尔值。因此,为了实际运行该块,您需要调用它。就像这样:

differentStrings(); 

,或者在你的情况:

if (differentStrings()) { 
    NSLog (@"strings are different"); 
} 

编辑:正如在评论中指出,由于differentStrings是一个实例变量,你需要copy它,就像你在任何其他分配给实例变量的对象上调用retain。 (由于技术原因,我现在不会进入,您应该始终使用copy而不是retain)。同样,您需要稍后调用release,也许在您的dealloc方法中。

3

,直到我看到Block和MulithreadingStanfords Developing Apps for iOS

+0

感谢一个很好的介绍,该录像带帮助理解它更深,但即使在看完之后我仍然有同样的问题,这个阶级也没有提到。 – SpaceDog 2011-01-06 14:02:15

4

我不相信你实际上是在执行块我不能让我的周围块的头。我认为你的代码应该是

if (differentStrings()) 
{ 
    NSLog (@"strings are different); 
} 

将一个块视为一个函数。我想你只是在检查块是否已被定义,而不是执行它。另外,如果您不需要访问块外部的NSString,则可以去掉__block限定符,并在块内部移动currentString声明。

如果您需要其他资源块,我会在我的高级iOS开发课程on iTunes U的秋季课程中介绍它们。我在Understanding Cocoa会话中描述块语法,以及它们在多线程会话中的Grand Central Dispatch中的使用。课程笔记还有一些示例应用程序的链接,这些应用程序以不同方式使用块。

我也不能推荐的足够高,你看WWDC 2010视频会议206 - 在iPhone和211上推出块和大中央调度 - 用大中央调度简化iPhone应用程序开发。

+0

`previousString`需要是`__block`变量,因为它的值在块的后续调用之间被引用。此外,该块需要在分配给伊娃时被复制,否则它将超出范围。 – 2011-01-06 17:38:16

+1

@丹尼尔 - 好点,我会误解他是如何使用该字符串的。 – 2011-01-06 18:27:53

+0

感谢Brad,我会检查出来。 – SpaceDog 2011-01-06 19:15:33