ios - 这个 block 返回是如何工作的?

标签 ios objective-c-blocks

我试图解释这个 block 代码:

场景 1

NSIndexSet* indexes = [[self.orderItems allKeys] indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        IODItem* key = obj;
        return [searchItem.name isEqualToString:key.name] && searchItem.price == key.price;
    }];

好的,我得到 self.orderItems 字典的所有键并将它们作为 id obj 传递给 block {}。在 block 内,该 obj 被分配给一个 IODItem *键。然后调用 isEqualToString 和比较器 == 一样返回 BOOL。这对我来说很有意义,因为该 block 的返回类型为 BOOL。那么它是如何填充索引的 NSIndexSet 的呢?

情景 2

NSArray* keys = [[self.orderItems allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        IODItem* item1 = (IODItem*)obj1;
        IODItem* item2 = (IODItem*)obj2;
        return [item1.name compare:item2.name];
    }];

所以我再次为该词典获取了 allKeys。然后我 sortArrayUsingComparator 并将键作为 obj1 和 obj2 传递?这令人困惑。 obj1 和 obj2 只是 [self.orderItems allKeys] 数组中的键?

然后我将这 2 个 objs 分配给不同的 IDOItem。然后我实际上返回了 items1 & 2?这又让人费解了。我以为我在填写一个 NSArray *keys。为什么我要退回 2 件东西?

情景 3

// 3 - Enumerate items and add item name and quantity to description
[keys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    IODItem* item = (IODItem*)obj;
    NSNumber* quantity = (NSNumber*)[self.orderItems objectForKey:item];
    [orderDescription appendFormat:@"%@ x%@\n", item.name, quantity];
}];

我正在枚举键数组(实际上是从场景 2 中获取的)并使用键 obj 并将其分配给 IODItem 项。但这是我迷路的地方......我拿了 objectForKey 项目并将其用作数量?如果 objectForKey 返回与该键配对的对象,并且键“item”引用 id obj,则该 id obj 是排序键数组中的键。所以它是一个键,而不是一个值!不是吗?

最佳答案

如果您将 block 视为具有参数和返回类型的方法,就不会太困惑。第一种方法只是遍历整个键集并确定它们是否通过了您创建的测试。如果您的 block 返回"is",那么它将被添加到新的索引集中。如果该 block 返回“NO”,则它会被忽略。生成的索引集将引用一组完整的通过测试的键。

第二种方法是一种对数组执行自定义排序的方法。根据哪个对象应该更接近数组的开头,您可以返回 NSOrderedAscending、NSOrderedSame 或 NSOrderedDescending。这可能会根据您的排序标准而改变。您基本上所做的是在第一个对象的“名称”属性上调用 compare: 方法。根据这是什么数据类型(我假设它是 NSString),您的 block 将调用 NSString 的 compare: 方法。如果它是一个 NSNumber 或另一个类,它会调用该类的 compare: 方法,等等。compare: 方法还返回一个 NSComparisonResult(三个选项之一上面列出的)。

添加了场景 3:

对于场景 3,在通过“键”进行枚举时,每个“id obj”都是字典中的键,而不是您编码的 IODItem。要获得适用的 IODItem,您可能需要做这样的事情(我假设 self.orderItems 指的是 NSDictionary 对象):

__block NSMutableString *orderDescription;
__block NSNumber *quantity;

[keys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
   NSString* currentKey = (NSString*)obj;
   IODItem *item = [self.orderItems objectForKey:currentKey];
   quantity = item.quantity;
   [orderDescription appendFormat:@"%@ x%@\n", item.name, quantity];
}];

关于ios - 这个 block 返回是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17499604/

相关文章:

ios - 在 Swift 中通过闭包捕获时不会释放对象

objective-c - ios 6 uilabel 文本不居中对齐

iphone - RootViewController - TableView :cellForRowAtIndexPath - Load image from assetsLibrary

objective-c - 如何使用 ARC 将 block 实例化为实例变量?

iphone - OpenGL ES-全局上下文错误中的限定符

ios - 将CLLocationCoordinate2D转换为PFGeoPoint吗?

ios - 字典中的自定义键

ios - Mantle 问题 - MTLValueTransformer 不会将 NSNumber 转换为 int

iphone - EXC_BAD_ACCESS 复制或保留 Block 时

objective-c-blocks - 在 iOS 上使用 Parse,如何在后台将两个 PFFiles 保存到一个 PFObject