Эквивалент контейнера C ++ STL "pair <T1, T2>" в Objective-C? - PullRequest
15 голосов
/ 19 августа 2010

Я новичок в Objective-C, поэтому, пожалуйста, не судите меня слишком сильно. Мне было интересно: есть ли эквивалент контейнера пары STL C ++, который я могу использовать в Objective-C?

Я хочу создать массив, содержащий NSInteger, связанный с NSBool. Я знаю, что могу использовать массив, в котором каждая запись является NSDictionary с одним значением ключа, но я считаю, что это немного излишне.

Есть идеи?

Спасибо.

Ответы [ 5 ]

16 голосов
/ 19 августа 2010

Вы можете написать свой собственный объект структуры данных - для такого простого случая это было бы довольно просто:

@interface Pair : NSObject 
{
    NSInteger integer;
    BOOL      boolean;
}
@property (nonatomic, assign) integer;
@property (nonatomic, assign) boolean;
@end

И соответствующая реализация, тогда вы вставляете свои Pair объекты в NSArray без проблем.

7 голосов
/ 19 августа 2010

Вы можете использовать STL в Objective-C ++. Все, что вам нужно сделать, это изменить расширение вашего файла .m на .mm, и я бы также посоветовал вам использовать #import вместо #include. Таким образом, вы можете использовать вашу пару STL контейнер.

1 голос
/ 19 августа 2010

Используя анонимные литералы struct и struct, вы можете сделать что-то вроде

NSValue * v = [NSValue valueWithBytes:(struct {NSInteger i; bool b;}){i,b} objCType:(struct {NSInteger i; bool b;})];

и затем прочитать,

struct {NSInteger i; bool b;} foo;
[v getValue:&foo];

Немного чище, если вы назовете свою структурухотя.

0 голосов
/ 18 марта 2019

Еще одним вариантом является (ab) использование NSDictionary с одной записью для хранения пары - поскольку NSDictionary теперь может быть определен для принудительного ввода типизированных «ключ» и «значение», а также поддерживает литералы как синтаксический сахар. Недостаток - пара может содержать только NSObjects (ссылки на экземпляры), а не примитивные значения.

Образец будет выглядеть так:

typedef NSDictionary<NSString *, NSDate *> *Pair;

А потом в вашем коде:

Pair myPair = @{@"my name": [NSDate date]};
Pair myOtherPair =  @{@"his name": [NSDate date]};
NSArray<Pair> *myArrayOfPairs = @[myPair, myOtherPair];

Перейдите и распечатайте результаты:

NSLog(@"%@", myArrayOfPairs);

и это очень похоже на то, что вы ожидаете.

2019-03-18 16:08:21.740667+0200 TesterApp[23135:23269890] (
  {
    "my name" = "2019-03-18 14:08:21 +0000";
  },
  {
    "his name" = "2019-03-18 14:08:21 +0000";
  }
)

Время окупаемости наступает, когда вы пытаетесь извлечь значения из так называемой «пары». На самом деле вы должны выкопать эту единственную запись из NSDictionary, а не по ее «Ключу», как обычно, но при условии, что есть только одна запись, например:

Pair somePair = myArrayOfPairs.lastObject;
NSString *name = somePair.allKeys.firstObject;
NSDate *date = somePair.allValues.firstObject;
NSLog(@"name: %@ date: %@", name, date);

что в итоге дает:

name: his name date: Mon Mar 18 16:16:43 2019

Я не особенно рекомендую эту альтернативу, но она имеет свои тонкости и преимущества.

0 голосов
/ 19 августа 2010

Как насчет категории Pair в NSNumber, которая использует связанные объекты, что-то вроде приведенного ниже кода (непроверенный, может потребоваться iOS4, поскольку я не уверен, когда были представлены связанные объекты).

#import <objc/runtime.h>

@implementation NSNumber(Pair)

#define PAIR_KEY 'p'

- (NSNumber *) pairNumber:(NSNumber *)second
{
    char secondKey = PAIR_KEY;
    objc_setAssociatedObject(self, &secondKey, second, OBJC_ASSOCIATION_RETAIN);
    return self;
}

- (NSNumber *) pairedNumber
{
    char secondKey = PAIR_KEY;
    NSNumber *associatedObject = (NSNumber *)objc_getAssociatedObject(self, &secondKey);    
    return associatedObject;
}

@end

Вы быиспользуйте это так:

BOOL myBool = NO;

NSNumber *storedBool = [NSNumber numberWithBool:myBool];

[myOtherNumber pairNumber:storedBool];

И чтобы получить это:

NSNumber *boolNumber = [myOtherNumber pairedNumber];
...