【问题标题】:Objective-C data type issueObjective-C 数据类型问题
【发布时间】:2021-12-12 21:47:20
【问题描述】:

我对 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: 吗?我很惊讶它本身并没有引发错误。这里的问题是,intlongNSInteger 等原始值不是对象(它们的内存是内联存储的,而不是在符合 Objective 的内存布局的堆分配对象中) C期望对象)。您需要使用模拟您的号码的对象,即NSNumber

标签: ios objective-c


【解决方案1】:

考虑到 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]);
    }];
}

【讨论】:

  • 虽然...现在我注意到了。如果您对ecuteWithCompletionBlock 的“错误”块有任何控制权,发送NSError 错误字典似乎有点愚蠢,因为NSError 具有域、代码和用户信息字典- 所以一切都可以在NSError中。
【解决方案2】:

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

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

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

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

【讨论】:

  • 仍然,如何定义错误块并正确传回 -1 值?
猜你喜欢
  • 1970-01-01
  • 2014-09-23
  • 2011-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多