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