【问题标题】:Is there a Queue/FIFO data structure for the iPhone?iPhone 有 Queue/FIFO 数据结构吗?
【发布时间】:2010-11-09 09:28:55
【问题描述】:

在我使用NSMutableArray 推出自己的队列 之前,我想知道是否有更标准的东西可用。我在 Apple 文档中看不到任何内容,但如果人们正在使用的某个地方没有 Queue 实现,我会感到惊讶。 Java 宠坏了我!

【问题讨论】:

    标签: iphone queue data-structures


    【解决方案1】:

    你可以使用 NSArray 的 :lastObject 方法。这是一个未经测试的示例:

    队列.h

    #import <Foundation/Foundation.h>
    
    @interface Queue : NSObject
    
    -(void)enqueue:(id)object;
    -(id)dequeue;
    
    @end
    

    队列.m

    #import "Queue.h"
    
    @interface Queue()
    
    @property(nonatomic, strong) NSMutableArray *backingArray;
    
    @end
    
    @implementation Queue
    
    -(id)init {
        self = [super init];
    
        if (self) {
            self.backingArray = [NSMutableArray array];
        }
        return self;
    }
    
    -(void)enqueue:(id<NSObject>)object {
        [self.backingArray addObject:object];
    }
    
    -(id)dequeue {
        id object = [self.backingArray lastObject];
        [self.backingArray removeObject:object];
        return object;
    }
    
    @end
    

    【讨论】:

      【解决方案2】:

      基于NSMutableArray 实现一个队列非常简单,大概不到 50 行代码。

      编辑:

      通过快速谷歌搜索找到了这个:

      @interface Queue:NSObject {
         NSMutableArray* objects;
      }
      - (void)addObject:(id)object;
      - (id)takeObject;
      @end
      
      @implementation Queue
      
      - (id)init {
         if ((self = [super init])) {
             objects = [[NSMutableArray alloc] init];    
         }
         return self;
      }
      
      - (void)dealloc {
          [objects release];
          [super dealloc];
      }
      
      - (void)addObject:(id)object {
         [objects addObject:object];
      }
      
      - (id)takeObject  {
         id object = nil;
         if ([objects count] > 0) {
             object = [[[objects objectAtIndex:0] retain] autorelease];
             [objects removeObjectAtIndex:0];
         }
         return object;
      }
      
      @end
      

      【讨论】:

      • +1 我清理了一些格式化代码和 -takeObject 方法。
      • 在你的 dealloc 上添加一个 [objects release] 我会给你一个 +1
      • 一个更好的实现是链表。使用链表,您可以将执行每个操作所花费的时间优化到 O(1)。使用 NSMutableArray,您对每个 takeObject 都有一个 O(n) 操作(removeObjectAtIndex 会将所有元素向下移动)。
      • 缺少 { 以打开 takeObject 的块。不错的答案,不过:) 谢谢!
      【解决方案3】:

      查看STL priority queue。它需要零行代码并且是可移植的!你还想要什么?

      【讨论】:

        【解决方案4】:

        您可以使用 C++ 标准库中的 STL 队列。

        【讨论】:

        • 我发现 Objective C++ 在 Xcode9 (9.2) 中存在迭代器问题。在我遇到的场景中,map 的迭代器无法正确检测 map->end()。我会尽量减少在纯 iOS 代码中使用的 c++ STL,并尝试让 c++ 与 C++ API 接口层。 C++ 代码的另一个复杂之处是内存管理,因为 ARC 不处理 C++ 对象。如果您习惯了 ARC 为您清理,请记住这点。
        【解决方案5】:

        我根据 Matt Bridges 代码创建了一个仅包含 deque 方法的类别。

        @interface NSMutableArray (ShiftExtension)
        // returns the first element of self and removes it
        -(id)shift;
        @end
        
        @implementation NSMutableArray (ShiftExtension)
        -(id)shift {
            if([self count] < 1) return nil;
            id obj = [[[self objectAtIndex:0] retain] autorelease];
            [self removeObjectAtIndex:0];
            return obj;
        }
        @end
        

        【讨论】:

          【解决方案6】:

          Cocoa 本身没有 Queue 类,本身也没有标准,但有多种选择,其中一种可能最适合您的需求。见this question(和my answer)。

          就像你说的,你可以使用 NSMutableArray 自己滚动。如果您只需要一个快速的'n'dirty 队列(并且不担心复制、编码/解码、枚举等),那么@Matt 建议的解决方案是一种简单的方法。您还应该考虑adding queue methods to NSMutableArray via a category,这很好,因为您的“队列”也是一个数组(因此您可以将它传递给 NSArray 参数),并且您可以免费获得所有 NS(Mutable)Array 功能。

          如果性能很重要,我建议使用更适合移除第一个元素的结构。正是出于这个原因,我为自己的框架写了CHCircularBufferQueue。 (不是想自吹自擂,只是想为别人节省一些时间。)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-12-21
            • 2021-07-29
            • 2011-11-17
            • 1970-01-01
            • 1970-01-01
            • 2011-02-08
            • 2013-06-05
            • 1970-01-01
            相关资源
            最近更新 更多