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]);
}];
}
我对 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]);
}];
}