Objective-C 数据类型问题

Objective-C data type issue

我对 Objective-C 不是很了解,所以这可能是一个简单的问题。我不明白为什么错误完成块中的最后一行导致异常:

- (void)sendInappropriateNewsfeedComment:(NSString *)comment newsfeedEventId:(NSString *)newsfeedEventId completion:(void (^)(NSString *, NSInteger))completion error:(void (^)(NSString *, NSInteger))error {
    PAInappropriateNewsFeedRequest *inappropriateNewsfeedRequest = [[PAInappropriateNewsFeedRequest alloc] initWithComment:comment newsfeedEventId:newsfeedEventId];
    [inappropriateNewsfeedRequest executeWithCompletionBlock:^(id obj) {
        completion(@"SUCCESS", (NSInteger)1);
    } error:^(NSError *e, id obj) {
        NSString * message = [obj objectForKey:@"message"];

        error(message, [obj integerForKey:@"code"]);
    }];
}

我还附上了一张截图,显示“obj”对象有一个名为“code”的键,类型为“(long)-1”。

声明错误块并将“-1”值传回调用站点的正确方法是什么?

仅仅是因为NSDictionary没有调用integerForKey的方法。这就是“无法识别的选择器”的意思。选择器基本上是一个方法名。

这个甚至可以编译的事实是由于参数类型使用id造成的。您可以在 id 上调用任何内容,但如果该方法不存在,它会使您的应用程序崩溃。您应该尽快将 obj 转换为正确的类型。

NSDictionary *dictionary = (NSDictionary *) obj;
NSString *message = dictionary[@"message"];
NSNumber *code = dictionary[@"code"];

如果 obj 可以是不同的类型,您应该确保在转换前检查 [obj isKindOfClass:NSDictionary.self]

考虑到 Sulthan 的建议的整个解决方案可能看起来像这样

typedef void (^NewFeedCompletion)(NSString *, NSInteger);
typedef void (^NewsFeedError)(NSString *, NSInteger);

- (void) sendInappropriateNewsfeedComment: (NSString *)comment
                          newsfeedEventId: (NSString *)newsfeedEventId
                               completion: (NewFeedCompletion) completion
                                    error: (NewsFeedError) error
{
    PAInappropriateNewsFeedRequest *inappropriateNewsfeedRequest = [[PAInappropriateNewsFeedRequest alloc] initWithComment:comment newsfeedEventId:newsfeedEventId];

    [inappropriateNewsfeedRequest executeWithCompletionBlock: ^(id obj) {
        completion(@"SUCCESS", (NSInteger)1);
    } error:^(NSError *e, id obj) {
        assert([obj isKindOfClass: NSDictionary.class])

        NSDictionary *errorDictionary = (NSDictionary *) obj;
        NSString *message = [errorDictionary objectForKey: @"message"];
        NSNumber *code = [errorDictionary objectForKey: @"code"]

        error(message, [code integerValue]);
    }];
}