尝试了解 iOS 上的块

发布于 2024-10-10 15:14:03 字数 1170 浏览 0 评论 0原文

我想了解如何在 iOS 上使用块。我已经阅读了苹果的文档,但像往常一样,它们是模糊且不完整的,并且没有提到一些重要的信息。我也用谷歌搜索过但没有成功。这就是我试图做的练习来理解这一点。

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

这就是我的做法:

我在 .h 上声明了这一点

BOOL (^differentStrings)(void);

我在 viewController 中的 viewDidLoad 内的 .m 上声明了

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

这些是我遇到的问题:

  1. 块总是返回 YES (字符串不同)
  2. 我不舒服在videDidLoad中声明这一点。我应该如何声明它,以便我可以在全局范围内使用它作为方法?我应该像使用方法一样来表达它吗?
  3. 我在块内调用方法“getString”。可以吗?
  4. 我觉得在 .m 上声明块变量很奇怪。正如我所见,我应该在 .h 上声明块变量,然后在 .m 上使用它们。我尝试这样做,但收到错误。
  5. 我在块的第一行设置了一个调试点,但它并没有停止在那里;
  6. 块内的 NSlog 行不打印任何内容。块没有被调用吗?

你们能帮我解决这个问题吗?

I am trying to understand how to use blocks on iOS. I have read Apple's docs but, as usual, they are vague and incomplete and several essential bits of information are not mentioned. I have also googled around without success. This is what I am trying to do as an exercise to understand that.

I have created a block to read a string and compare the string to the previous read. If the strings are not the same, return YES, if they are the same, return NO.

This is how I did:

I declared this on .h

BOOL (^differentStrings)(void);

I declared this on .m, inside viewDidLoad in a 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;
    }
};

This is how I use: I have a thread that does this:

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

These are the problems I have:

  1. the block always return YES (strings are different)
  2. I am not comfortable declaring this inside videDidLoad. How should I declare this, so I can use it globally as a method? Should I put this like I would with a method?
  3. I am calling a method "getString" inside the block. Is it OK?
  4. I find strange to declare the block variables on .m. As I see, I should declare the block variables on .h and then just use them on .m. I have tried to do that, but received an error.
  5. I have setup a debugging point on the first line of the block but it is not stopping there;
  6. NSlog line inside the block do not prints anything. Isn't the block being called?

Can you guys help me with this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蔚蓝源自深海 2024-10-17 15:14:03

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

__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 < /code> 包含 0 或 NULL 以外的内容。由于它包含一个块,因此它不为空,因此计算结果为 true。

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

differentStrings();

或者,在您的情况下:

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

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

You're misunderstanding how blocks work. (Okay, so that's kinda obvious.) In the same way that previousString is a variable pointing to an NSString, differentStrings is a variable pointing to a block. Not the result of running the block, but rather, the block itself. That is, after you do this:

__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 is a variable pointing to the block.Thus, when you do this:

if (differentStrings)

…you're simply checking whether differentStrings contains something other than 0 or NULL. Since it contains a block, it is not empty, so it evaluates to true.

Remember: differentStrings is a block variable, not a BOOL variable. It contains a block (a function, if you will), which when called will return a bool. Thus, in order to actually run the block, you need to call it. Like this:

differentStrings();

or, in your case:

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

Edit: As pointed out in the comments, since differentStrings is an instance variable, you need to copy it, just like you'd call retain on any other object assigned to an instance variable. (For technical reasons I won't go into now, you should always use copy with blocks instead of retain.) Likewise, you'll need to call release on it at some point later, perhaps in your dealloc method.

薯片软お妹 2024-10-17 15:14:03

我不相信你实际上正在执行该块。我认为你的代码应该

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

像函数一样对待块。我认为您只是检查该块是否已定义,而不是执行它。

另外,如果您不需要访问块外部的 NSString,则可以去掉 __block 限定符并将 currentString 声明移动到块内部。

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

我也极力推荐您观看 WWDC 2010 视频会议 206 -在 iPhone 和 211 上引入 Blocks 和 Grand Central Dispatch - 使用 Grand Central Dispatch 简化 iPhone 应用程序开发。

I don't believe you're actually executing the block. I think your code should be

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

Treat a block like a function. I think you were just checking to see whether the block had been defined, not executing it.

Also, if you don't need to access an NSString outside of the block, you could get rid of the __block qualifier and move the currentString declaration inside of the block.

If you need another resource on blocks, I cover them in the fall session of my advanced iOS development course on iTunes U. I describe block syntax in the Understanding Cocoa session, and their use in Grand Central Dispatch within the multithreading session. The course notes also have links to some sample applications that use blocks in different ways.

I also can't recommend highly enough that you watch the WWDC 2010 video sessions 206 - Introducing Blocks and Grand Central Dispatch on iPhone and 211 - Simplifying iPhone App Development with Grand Central Dispatch.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文