1
votes

I'm having trouble understanding how to use subclassed objects with blocks. Here is an example of what I'm trying. PFItem is a subclass of PFObject.

- (void) handleItem:(PFItem *)item{
    [item fetchIfNeededInBackgroundWithBlock:^(PFItem *item, NSError *error) {
        if (!error) {
            if ([item.name  isEqualToString:@"Antidote"]) {
                NSLog(@"Applied %@", item.name);
                NSMutableArray *discardItems = [NSMutableArray array];
                for (PFItem *item in self.pfButtonCharacter.itemsApplied) {
                    if (item.malicious) {
                        [discardItems addObject:item];
                        NSLog(@"Removing %@", item.name);
                    }
                }
                [PFObject deleteAll:discardItems];
            }
        }
    }];
}

However, xcode flags this as a semantic error:

Incompatible block pointer types sending 'void (^)(PFItem *__strong, NSError *__strong)' to parameter of type 'PFObjectResultBlock' (aka 'void (^)(PFObject *__strong, NSError *__strong)')

If I change from PFItem to PFObject in fetchIfNeededInBackgroundWithBlock, it works, but then I can no longer access the properties of item. Instead of item.name I need to do item[@"name"].

2

2 Answers

2
votes

If the method specifies you must use a block that takes a PFObject argument rather than a PFItem argument, then you must use a block that matches that for the method.

If you know the object being sent is actually a PFItem, you can always cast it within the block:

[item fetchIfNeededInBackgroundWithBlock:^(PFObject *obj, NSError *error) {
    PFItem *item;
    if ([obj isKindOfClass:[PFItem class]]) {
        item = (PFItem *)obj;
    } else {
        return;
    }
    if (!error) {
        if ([item.name  isEqualToString:@"Antidote"]) {
            NSLog(@"Applied %@", item.name);
            NSMutableArray *discardItems = [NSMutableArray array];
            for (PFItem *item in self.pfButtonCharacter.itemsApplied) {
                if (item.malicious) {
                    [discardItems addObject:item];
                    NSLog(@"Removing %@", item.name);
                }
            }
            [PFObject deleteAll:discardItems];
        }
    }
}];
1
votes
- (void) handleItem:(PFItem *)item{
[item fetchIfNeededInBackgroundWithBlock:^(PFObject *pfObj, NSError *error) {
    PFItem *item = (PFItem *)pfObj;
    if (!error) {
        if ([item.name  isEqualToString:@"Antidote"]) {
            NSLog(@"Applied %@", item.name);
            NSMutableArray *discardItems = [NSMutableArray array];
            for (PFItem *item in self.pfButtonCharacter.itemsApplied) {
                if (item.malicious) {
                    [discardItems addObject:item];
                    NSLog(@"Removing %@", item.name);
                }
            }
            [PFObject deleteAll:discardItems];
        }
    }
}];
}

Cast the PFObject to a PFItem and you're done. This is assuming that the PFObject is actually a PFItem.