如何使用块处理循环代码?

编程入门 行业动态 更新时间:2024-10-27 00:24:42
本文介绍了如何使用块处理循环代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一些需要使用块的代码。该块从Web服务中获取大量数据项,然后可能需要获取更多数据项,然后再获取更多数据项,然后在完全需要后返回所有数据项。我不确定如何将其放入代码中。这是我的意思的一个例子:

NSMutableArray * array = [[NSMutableArray alloc] init]; [webService getLatestItemsWithCount:50 completion:^(NSArray * objects){ //处理这些项目的一些代码。 if(moreItemsNeeded == YES){ //我现在需要它来循环这个块,直到我完成} }];

我怎样才能让它发挥作用?

<编辑:

好的,这就是我正在使用的 - 它是Evernote API。它应该是我需要的更好的例子:

[noteStore findNotesMetadataWithFilter:filter offset:0 maxNotes:100 resultSpec:resultSpec success:^(EDAMNotesMetadataList * metadataList){ for(EDAMNoteMetadata * metadataList.notes中的元数据){ NSDate * timestamp = [NSDate endateFromEDAMTimestamp :metadata.updated]; if(timestamp.timeIntervalSince1970> date.timeIntervalSince1970){ [array addObject:metadata]; } else { arrayComplete = YES; } } //我需要它来循环这段代码,增加偏移量,直到数组完成。 }失败:^(NSError *错误){ NSLog(@失败:%@,错误); }];

解决方案

您应该创建一个引用要生成的块的变量可能是递归调用。必须注意的是,在你分配块时,它仍然是 nil ,所以如果你在块本身(也就是递归)中调用它,你会在尝试执行时遇到崩溃 nil 块。所以块应该有* __ block *存储:

void(^ __ block myBlock)(NSArray *)= ^(NSArray *对象){ //处理这些项目的一些代码。 if(moreItemsNeeded == YES){ //我现在需要它循环这个块直到我完成 myBlock(objects); myBlock = nil; //避免保留周期} }]; [webService getLatestItemsWithCount:50 completion:myBlock];

特定情况下的区块被翻译为:

void(^ __块处理程序)(EDAMNotesMetadataList)= ^(EDAMNotesMetadataList * metadataList){ for(EDAMNoteMetadata * metadataList.notes中的元数据){ NSDate * timestamp = [NSDate endateFromEDAMTimestamp:metadata.updated]; if(timestamp.timeIntervalSince1970> date.timeIntervalSince1970){ [array addObject:metadata]; } else { arrayComplete = YES; } } //我需要它来循环这段代码,增加偏移量,直到数组完成。 if(!arrayComplete) handler(metadataList); handler = nil; //避免保留周期};

然后您通常可以将 myBlock 作为参数调用该方法。

关于保留周期

为了避免保留周期,您应该设置为 nil 递归完成时指向块的指针。

I have some code which requires the use of blocks. The block fetches a number of data items from a web service, and then possibly needs to fetch more, and then more again after that, then returns all of the data items once it has all required. I'm unsure how to put this into code. Here's an example of what I mean:

NSMutableArray *array = [[NSMutableArray alloc] init]; [webService getLatestItemsWithCount:50 completion:^(NSArray *objects) { //Some code to deal with these items. if (moreItemsNeeded == YES) { //I now need it to loop this block until I'm done } }];

How can I get this to work?

EDIT:

Ok, this is what i'm working with - it's the Evernote API. It should be a better example of what I need:

[noteStore findNotesMetadataWithFilter:filter offset:0 maxNotes:100 resultSpec:resultSpec success:^(EDAMNotesMetadataList *metadataList) { for (EDAMNoteMetadata *metadata in metadataList.notes) { NSDate *timestamp = [NSDate endateFromEDAMTimestamp:metadata.updated]; if (timestamp.timeIntervalSince1970 > date.timeIntervalSince1970) { [array addObject:metadata]; } else { arrayComplete = YES; } } //I need it to loop this code, increasing the offset, until the array is complete. }failure:^(NSError *error) { NSLog(@"Failure: %@", error); }];

解决方案

You should create a variable that references the block to make possible the recursive invocation. It must be noted that at the moment that you assign the block, it is still nil, so if you call it inside the block itself (aka recursively), you'll get a crash while trying to execute a nil block. So the block should have a *__block* storage:

void (^__block myBlock) (NSArray*) = ^(NSArray *objects) { //Some code to deal with these items. if (moreItemsNeeded == YES) { //I now need it to loop this block until I'm done myBlock(objects); myBlock= nil; // Avoid retain cycle } }]; [webService getLatestItemsWithCount:50 completion: myBlock];

The block in your specific case is "translated" as this one:

void (^__block handler) (EDAMNotesMetadataList)= ^(EDAMNotesMetadataList* metadataList) { for (EDAMNoteMetadata *metadata in metadataList.notes) { NSDate *timestamp = [NSDate endateFromEDAMTimestamp:metadata.updated]; if (timestamp.timeIntervalSince1970 > date.timeIntervalSince1970) { [array addObject:metadata]; } else { arrayComplete = YES; } } //I need it to loop this code, increasing the offset, until the array is complete. if(!arrayComplete) handler(metadataList); handler= nil; // Avoid retain cycle };

Then you can normally call that method passing myBlock as argument.

About retain cycles

To avoid a retain cycle, you should set to nil the pointer to the block when the recursion finishes.

更多推荐

如何使用块处理循环代码?

本文发布于:2023-11-29 19:16:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1647375.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何使用   代码

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!