Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 试图理解iOS上的块_Iphone_Objective C Blocks - Fatal编程技术网

Iphone 试图理解iOS上的块

Iphone 试图理解iOS上的块,iphone,objective-c-blocks,Iphone,Objective C Blocks,我试图了解如何在iOS上使用块。我读过苹果公司的文件,但和往常一样,这些文件含糊不清,不完整,一些重要的信息没有提及。我也在谷歌上四处搜索,但没有成功。这就是我试图做的,作为一个练习来理解这一点 我创建了一个块来读取字符串,并将该字符串与以前读取的字符串进行比较。如果字符串不相同,则返回YES;如果字符串相同,则返回NO 我就是这样做的: 我是在……上申报的 BOOL (^differentStrings)(void); 我在.m中声明了这一点,在viewController中的viewDid

我试图了解如何在iOS上使用块。我读过苹果公司的文件,但和往常一样,这些文件含糊不清,不完整,一些重要的信息没有提及。我也在谷歌上四处搜索,但没有成功。这就是我试图做的,作为一个练习来理解这一点

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

我就是这样做的:

我是在……上申报的

BOOL (^differentStrings)(void);
我在.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;
    }
};
我是这样使用的:我有一个线程可以:

if (differentStrings)
  NSLog (@"strings are different);
以下是我遇到的问题:

  • 块始终返回YES(字符串不同)
  • 我不喜欢在视频加载中声明这一点。我应该如何声明它,以便全局使用它作为方法?我应该用一种方法来表达这一点吗
  • 我正在块内调用一个方法“getString”。可以吗
  • 我发现在.m上声明块变量很奇怪。如我所见,我应该在.h上声明块变量,然后在.m上使用它们。我尝试过这样做,但收到了一个错误
  • 我已经在块的第一行设置了一个调试点,但它并没有停在那里
  • 块内的NSlog行不打印任何内容。这个街区不是被叫来了吗

  • 你们能帮我一下吗?

    我不相信你们真的在执行这个程序块。我认为你的代码应该是

    if (differentStrings())
    {
        NSLog (@"strings are different);
    }
    
    将块视为函数。我认为您只是检查块是否已定义,而不是执行它

    此外,如果不需要访问块外的NSString,可以去掉
    \uu块
    限定符,并将
    currentString
    声明移到块内

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


    我还极力推荐您观看视频会话206——在iPhone上介绍Blocks和Grand Central Dispatch,以及211——使用Grand Central Dispatch简化iPhone应用程序开发。

    您误解了Blocks的工作原理。(好的,这很明显。)正如
    previousString
    是一个指向NSString的变量一样,
    differentString
    也是一个指向块的变量。不是运行块的结果,而是块本身。也就是说,在执行此操作之后:

    __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;
        }
    };
    
    if (differentStrings)
    
    differentString
    是一个指向块的变量。因此,执行此操作时:

    __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;
        }
    };
    
    if (differentStrings)
    
    …您只需检查
    differentString
    是否包含0或NULL以外的内容。因为它包含一个块,所以它不是空的,所以它的计算结果为true

    请记住:
    differentString
    是块变量,而不是布尔变量。它包含一个块(一个函数,如果您愿意的话),调用该块时将返回bool。因此,为了实际运行该块,您需要调用它。像这样:

    differentStrings();
    
    或者,在您的情况下:

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

    Edit:正如注释中指出的,由于
    differentitstrings
    是一个实例变量,因此需要
    copy
    它,就像在分配给实例变量的任何其他对象上调用
    retain
    一样。(出于技术原因,我现在不想讨论,您应该始终对块使用
    copy
    ,而不是
    retain
    )同样,您需要在以后的某个时候调用
    release
    ,可能是在
    dealloc
    方法中。

    我认为在分配给ivar时,您还需要
    复制
    块。否则,当退出
    viewDidLoad
    时,该块将超出范围。另外,
    previousString
    确实需要是一个
    \u块
    变量,
    currentString
    可以是一个块局部变量。谢谢您的回答。我在调用块时添加了括号,在viewDidLoad上创建块后也进行了块拷贝(DifferentString),但当我使用DifferentString()调用块时,它崩溃了。。。我试着从同一个作用域调用该块,但当我从另一个作用域调用它时,它崩溃了,即使使用了block_copy。那么,您必须查看它崩溃的位置。我的猜测是,getString方法返回一个自动释放的对象,当您执行previousString=currentString时,您没有保留它。因此,当您稍后尝试查看它时,它会崩溃。
    previousString
    需要是一个
    \u块
    变量,因为它的值在随后的块调用之间被引用。另外,当分配给ivar时,需要复制块,否则它将超出范围。@丹尼尔-好的,我误读了他是如何使用该字符串的。谢谢Brad,我会检查它。在我看到块和Mulithreading之前,我无法理解块