在 Objective-C 中是否有等效于 C++ 的动态转换? [英] Is there an equivalent to C++'s dynamic cast in Objective-C?

查看:56
本文介绍了在 Objective-C 中是否有等效于 C++ 的动态转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有两个类,SubClass 和 SuperClass:

If I have two classes, SubClass and SuperClass:

SuperClass *super = new SuperClass();
SubClass *sub = new SubClass();
SubClass *sub_pointer;

// **The nice one-line cast below**
sub_pointer = dynamic_cast<SubClass*> super;
// Prints NO
printf("Is a subclass: %s\n", sub_pointer ? "YES" : "NO");

sub_pointer = dynamic_cast<SubClass*> sub;
// Prints YES
printf("Is a subclass: %s\n", sub_pointer ? "YES" : "NO");

我可以使用 isMemberOfClass 在 Objective-C 中完成同样的事情,如下所示:

I can accomplish the same thing in objective-C with isMemberOfClass as follows:

SuperClass *super = [[SuperClass alloc] init];
SubClass *sub = [[SubClass alloc] init];
SubClass *sub_pointer;
id generic_pointer;

// Not as easy:
generic_pointer = super;
if ([generic_pointer isMemberOfClass:[SubClass class]]) {
  sub_pointer = generic_pointer;
} else {
  sub_pointer = nil;
}
// Logs NO
NSLog(@"Is a subclass: %@", sub_pointer ? @"YES" : @"NO");

generic_pointer = sub;
if ([generic_pointer isMemberOfClass:[SubClass class]]) {
  sub_pointer = generic_pointer;
} else {
  sub_pointer = nil;
}
// Logs YES
NSLog(@"Is a subclass: %@", sub_pointer ? @"YES" : @"NO");

还有比这更简单的方法吗?

Is there an easier way than this?

(PS 我知道我不必使用额外的 id 变量,但随后我将不得不强制将 super 强制转换为 SubClass*,这有时会导致我必须在事后清理的无效引用.那然而,实现不那么冗长,它在下面)

(P.S. I know I don't have to use the extra id variable, but then I would have to force cast super to SubClass*, which would sometimes result in an invalid reference that I would have to clean up afterwards. That implementation, however, is less wordy, and it's below)

SuperClass *super = [[SuperClass alloc] init];
SubClass *sub = [[SubClass alloc] init];
SubClass *sub_pointer;

// Not as easy:
sub_pointer = (SubClass*) super;
if (![sub_pointer isMemberOfClass:[SubClass class]]) {
  sub_pointer = nil;
}
// Logs NO
NSLog(@"Is a subclass: %@", sub_pointer ? @"YES" : @"NO");

sub_pointer = (SubClass*) sub;
if (![sub_pointer isMemberOfClass:[SubClass class]]) {
  sub_pointer = nil;
}
// Logs YES
NSLog(@"Is a subclass: %@", sub_pointer ? @"YES" : @"NO");

推荐答案

你可以在 NSObject 上添加一个类别来添加你想要的功能.

You could add a category on NSObject to add the functionality you want.

//NSObject+DynamicCast.h
@interface NSObject (DynamicCast)
-(id)objectIfMemberOfClass:(Class)aClass;
@end

//NSObject+DynamicCast.m
@implementation NSObject (DynamicCast)
-(id)objectIfMemberOfClass:(Class)aClass;
{
  return [self isMemberOfClass:aClass] ? self : nil;
}
@end

然后你可以这样做:

SuperClass *super = [[SuperClass alloc] init];
SubClass *sub = [[SubClass alloc] init];
SubClass *sub_pointer;
id generic_pointer;

// **The nice one-line cast below**
sub_pointer = [super objectIfMemberOfClass:[SubClass class]];
// Prints NO
printf("Is a subclass: %s\n", sub_pointer ? "YES" : "NO");

sub_pointer = [sub objectIfMemberOfClass:[SubClass class]];
// Prints YES
printf("Is a subclass: %s\n", sub_pointer ? "YES" : "NO");

这篇关于在 Objective-C 中是否有等效于 C++ 的动态转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆