문제

목표 C 프로그램에서 큐 데이터 구조를 사용하고 싶습니다. C ++에서는 STL 큐를 사용합니다. Objective-C의 동등한 데이터 구조는 무엇입니까? 푸시/팝 아이템은 어떻게하나요?

도움이 되었습니까?

해결책

Ben의 버전은 큐 대신 스택이므로 약간 조정했습니다.

NSMUTABLEARRAY+QUEUEDDITIONS.H

@interface NSMutableArray (QueueAdditions)
- (id) dequeue;
- (void) enqueue:(id)obj;
@end

NSMUTABLEARRAY+QUEUEDDITIONS.M

@implementation NSMutableArray (QueueAdditions)
// Queues are first-in-first-out, so we remove objects from the head
- (id) dequeue {
    // if ([self count] == 0) return nil; // to avoid raising exception (Quinn)
    id headObject = [self objectAtIndex:0];
    if (headObject != nil) {
        [[headObject retain] autorelease]; // so it isn't dealloc'ed on remove
        [self removeObjectAtIndex:0];
    }
    return headObject;
}

// Add to the tail of the queue (no one likes it when people cut in line!)
- (void) enqueue:(id)anObject {
    [self addObject:anObject];
    //this method automatically adds to the end of the array
}
@end

새 방법을 사용하려는 곳에서 .h 파일을 가져오고 다른 nsmutablearray 방법처럼 호출하십시오.

행운을 빕니다. 계속 코딩하십시오!

다른 팁

나는 nsmutablearray를 사용하는 것이 반드시 베스트 솔루션, 특히 범주가있는 메소드를 추가하는 경우 취약성으로 인해 메소드 이름이 충돌하면 발생할 수 있습니다. 빠른 큐티 큐의 경우, 메소드를 사용하여 돌연변이가있는 배열 끝에서 추가하고 제거합니다. 그러나 대기열을 재사용 할 계획이거나 코드가 더 읽기 쉽고 자명하기를 원한다면 전용 대기열 클래스가 원하는 것일 수 있습니다.

코코아에는 내장 된 내장이 없지만 다른 옵션이 있으며 처음부터 쓸 필요가 없습니다. 끝에서만 추가하고 제거하는 실제 대기열의 경우 원형 버퍼 배열은 매우 빠른 구현입니다. 체크 아웃 chdatrastructures.framework, 내가 작업 한 Objective-C의 라이브러리/프레임 워크. 그것은 다양한 큐를 구현할뿐만 아니라 스택, deques, 정렬 된 세트 등을 가지고 있습니다. chcircularbufferqueue NSMutableArray를 사용하는 것보다 훨씬 빠르고 (즉, 벤치 마크로 입증 될 수 있고) 더 읽기 쉬운 (주관적)입니다.

C ++ STL 클래스 대신 기본 Objective-C 클래스를 사용하는 데있어 가장 큰 장점은 코코아 코드와 완벽하게 통합되며 Encode/Decode (Serialization)에서 훨씬 더 잘 작동한다는 것입니다. 또한 쓰레기 수집 및 빠른 열거 (모두 10.5+에 존재하지만 iPhone의 후자 만)와 완벽하게 작동하며 대물 픽 객체와 C ++ 객체가 무엇인지 걱정할 필요가 없습니다.

마지막으로, NSMutableAreray는 어느 쪽 끝에서 추가 및 제거 할 때 표준 C 어레이보다 낫지 만, 큐의 가장 빠른 솔루션도 아닙니다. 대부분의 응용 프로그램의 경우 만족 스럽지만 속도가 필요한 경우 원형 버퍼 (또는 경우에 따라 링크 된 목록이 캐시 라인을 뜨겁게 유지하도록 최적화) NSMutableARRay를 쉽게 트립 할 수 있습니다.

내가 아는 한, Objective-C는 큐 데이터 구조를 제공하지 않습니다. 가장 좋은 방법은 NSMutableArray, 그런 다음 사용합니다 [array lastObject], [array removeLastObject] 항목을 가져 오기 위해 [array insertObject:o atIndex:0]...

이 작업을 많이하는 경우 Objective-C 범주를 작성하여 기능을 확장 할 수 있습니다. NSMutableArray 수업. 카테고리는 기존 클래스에 함수를 동적으로 추가 할 수 있습니다 (소스가없는 클래스조차도) - 다음과 같은 대기열을 만들 수 있습니다.

(참고 :이 코드는 실제로 대기열이 아닌 스택 용입니다. 아래 주석 참조)

@interface NSMutableArray (QueueAdditions)

- (id)pop;
- (void)push:(id)obj;

@end

@implementation NSMutableArray (QueueAdditions)

- (id)pop
{
    // nil if [self count] == 0
    id lastObject = [[[self lastObject] retain] autorelease];
    if (lastObject)
        [self removeLastObject];
    return lastObject;
}

- (void)push:(id)obj
{
     [self addObject: obj];
}

@end

실제 대기열 컬렉션 클래스는 없지만 NSMutableARRAY는 효과적으로 동일한 것을 사용할 수 있습니다. 당신은 a를 정의 할 수 있습니다 범주 원하는 경우 편의성으로 팝/푸시 방법을 추가하려면.

예, NSMutableARRAY를 사용하십시오. NSMutableArray는 실제로입니다 구현 2-3 트리; 일반적으로 임의의 지수에서 nsmutablearray에서 객체를 추가하거나 제거하는 성능 특성에 대해 자신을 염려하지 않아도됩니다.

Re : Wolfcow- 다음은 Wolfcow의 Dequeue 방법의 수정 된 구현입니다.

- (id)dequeue {
    if ([self count] == 0) {
        return nil;
    }
    id queueObject = [[[self objectAtIndex:0] retain] autorelease];
    [self removeObjectAtIndex:0];
    return queueObject;
}

카테고리를 사용하는 솔루션 NSMutableArray 왜냐하면 진정한 대기열이 아닙니다 NSMutableArray 대기열의 슈퍼 세트 인 작업을 노출시킵니다. 예를 들어, 큐 가운데에서 항목을 제거 할 수 없어야합니다 (해당 범주 솔루션에서 여전히 수행 할 수 있으므로). 객체 지향 설계의 주요 원리 인 기능을 캡슐화하는 것이 가장 좋습니다.

stdqueue.h

#import <Foundation/Foundation.h>

@interface StdQueue : NSObject

@property(nonatomic, readonly) BOOL empty;
@property(nonatomic, readonly) NSUInteger size;
@property(nonatomic, readonly) id front;
@property(nonatomic, readonly) id back;

- (void)enqueue:(id)object;
- (id)dequeue;

@end

stdqueue.m

#import "StdQueue.h"

@interface StdQueue ()

@property(nonatomic, strong) NSMutableArray* storage;

@end

@implementation StdQueue

#pragma mark NSObject

- (id)init
{
    if (self = [super init]) {
        _storage = [NSMutableArray array];
    }
    return self;
}

#pragma mark StdQueue

- (BOOL)empty
{
    return self.storage.count == 0;
}

- (NSUInteger)size
{
    return self.storage.count;
}

- (id)front
{
    return self.storage.firstObject;
}

- (id)back
{
    return self.storage.lastObject;
}

- (void)enqueue:(id)object
{
    [self.storage addObject:object];
}

- (id)dequeue
{
    id firstObject = nil;
    if (!self.empty) {
        firstObject  = self.storage.firstObject;
        [self.storage removeObjectAtIndex:0];
    }
    return firstObject;
}

@end

이것이 나의 구현입니다. 도움이되기를 바랍니다.

일종의 미니멀리즘이므로 팝에 새 머리를 저장하고 오래된 머리를 버림으로써 머리를 추적해야합니다.

@interface Queue : NSObject {
    id _data;
    Queue *tail;
}

-(id) initWithData:(id) data;
-(id) getData;

-(Queue*) pop;
-(void) push:(id) data;

@end

#import "Queue.h"

@implementation Queue

-(id) initWithData:(id) data {
    if (self=[super init]) {
        _data = data;
        [_data retain];
    }
    return self;
}
-(id) getData {
    return _data;
}

-(Queue*) pop {
    return tail;
}
-(void) push:(id) data{
    if (tail) {
        [tail push:data];
    } else {
        tail = [[Queue alloc]initWithData:data];
    }
}

-(void) dealloc {
    if (_data) {
        [_data release];
    }
    [super release];
}

@end

STL 대기열을 사용할 수없는 특별한 이유가 있습니까? 목적 C ++는 C ++의 슈퍼 세트입니다 (목적 C 대신 목표 C ++를 사용하기 위해 .m 대신 .m로 .mm을 사용). 그런 다음 STL 또는 기타 C ++ 코드를 사용할 수 있습니다.

목적 C 객체와 함께 STL 큐/벡터/목록 등을 사용하는 한 가지 문제는 일반적으로 RETAIN/RELEASE/AUTOREESEME MEMURAN MANCANAMANT를 지원하지 않는다는 것입니다. 이것은 C ++ 스마트 포인터 컨테이너 클래스와 쉽게 작업하여 구축시 목표 C 객체를 유지하고 파괴 될 때 해제합니다. STL 대기열에 넣는 것에 따라 종종 필요하지 않습니다.

nsmutablearray를 사용하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top