【问题标题】:How to create a typed stack using Objective-C如何使用 Objective-C 创建类型化堆栈
【发布时间】:2011-07-12 07:34:14
【问题描述】:

但是,我可以很容易地创建一个堆栈类,使用 NSArray 的 push 和 pop 访问器方法。我可以使这个泛型采用任何 NSObject 派生类,但是,我只想在这个堆栈中存储一个特定的类。

理想情况下,我想创建类似于 Java 的类型化列表(List 或 List)的东西,以便我只能将该类型存储在堆栈中。我可以为每个类(ProjectStack 或 ItemStack)创建一个不同的类,但这会导致文件结构更加复杂。

有没有办法将我可以添加到容器的类的类型限制为特定的、可配置的类型?

【问题讨论】:

标签: objective-c collections stack strong-typing


【解决方案1】:

NSArray 将采用与 NSObject 实现相同协议的任何对象;它不需要从 NSObject 派生。由于 Objective-C 中的所有调度都是动态的,因此多态不需要继承。

除此之外,如果您实现了自己的 push 和 pop 方法,您可以使用 isKindOfClassisMemberOfClass 轻松测试传入的类型并拒绝那些不正确的类型。

为了进一步了解,NSMutableArray 在页面顶部的“概述”部分的“子类化注释”标题下方记录了哪些方法在概念上是原始的。如果你继承 NSMutableArray 并改变 addObject:、replaceObjectAtIndex:withObject: 和 insertObject:atIndex: 来测试传入对象的类型,那么你可以创建一个类型化数组。

【讨论】:

    【解决方案2】:

    你可以试试这样的,虽然我不推荐:

    @interface TypedMutableStack : NSObject {
       Class type;
    @private
       NSMutableArray *internal;
    }
    
    - (id) initWithType:(Class) type_;
    
    @end
    
    #define CHECK_TYPE(obj) if(![obj isKindOfClass:type]) {\
          [NSException raise:NSInvalidArgumentException format:@"Incorrect type passed to TypedMutableStack"];\
     }
    
    
    @implementation TypedMutableStack
    
    - (void) dealloc {
      [internal release];
      [super dealloc];
    }
    
    - (id) initWithType:(Class) type_ {
       self = [super init];
       if(self) {
          type = type_;
          internal = [[NSMutableArray alloc] init];
       }
       return self;
    }
    
    - (void) addObject:(id) obj {
       CHECK_TYPE(obj);
       [internal addObject:obj];
    }
    
    - (void) replaceObjectAtIndex:(NSUInteger) index withObject:(id) obj {
        CHECK_TYPE(obj);
        [internal replaceObjectAtIndex:index withObject:obj];
    }
    
    - (void) insertObject:(id) obj atIndex:(NSUInteger) index {
        CHECK_TYPE(obj);
        [internal insertObject:obj atIndex:index];
    }
    
    //...
    @end
    

    【讨论】:

    • 这行不通; NSMutableArrayNSArray 是抽象的。您不能对它们进行子类化,也不能提供自己的存储机制。执行此操作的简单方法是添加 NSMutableArray ivar 并转发到该地址而不是 super
    • 好多了。为了保持一致,我也会抛出一个NSInvalidArgumentException,但这只是我的风格。 :)(不需要这样发明一个新的异常名称)
    【解决方案3】:

    Objective-C 没有泛型或模板。因此,惯用的 Objective-C 代码在任何地方都使用 NSObject *id 编写,并根据需要进行强制转换。

    无论您想做什么,都应该在现有框架上进行建模。看看 NSArray、NSDictionary、NSSet 等是如何实现的,跟风吧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-05
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多