You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Objective-C中实现C++的vector-pair功能及解决取值问题

解决Objective-C中存储类似C++ pair并取值、排序的问题

作为Objective-C新手,你遇到的核心问题是NSMutableArray只能存储Objective-C对象,不能直接存C语言结构体——你之前能存入是因为可能隐式做了包装,但取出时没正确还原结构体,导致取值错误。下面分两部分帮你解决:

一、正确取出结构体的方法

假设你定义的结构体是这样的(对应C++的pair<ll, int>):

typedef long long ll;
typedef struct {
    ll first;
    int second;
} MyPair;

存入时的正确操作

必须用NSValue把结构体包装成Objective-C对象,才能存入NSMutableArray:

NSMutableArray *pairArray = [NSMutableArray array];

// 创建结构体实例
MyPair pair1 = {123LL, 45};
// 用NSValue包装结构体
NSValue *pairValue1 = [NSValue valueWithBytes:&pair1 objCType:@encode(MyPair)];
[pairArray addObject:pairValue1];

// 可以继续添加更多结构体
MyPair pair2 = {78LL, 9};
NSValue *pairValue2 = [NSValue valueWithBytes:&pair2 objCType:@encode(MyPair)];
[pairArray addObject:pairValue2];

取出时的正确操作

从数组中拿到NSValue后,需要调用getValue:方法把结构体还原出来:

// 取出第一个元素
NSValue *targetValue = pairArray[0];
MyPair retrievedPair;
// 把NSValue中的数据拷贝到结构体变量里
[targetValue getValue:&retrievedPair];

// 现在可以正常访问结构体的值了
NSLog(@"First: %lld, Second: %d", retrievedPair.first, retrievedPair.second);

二、更简便的实现方式

用NSValue包装结构体虽然可行,但步骤繁琐,对于新手来说,更推荐两种更直观的方案:

方案1:自定义Objective-C类(最推荐)

直接创建一个类来模拟pair,类型安全且操作简单:

// Pair.h
#import <Foundation/Foundation.h>
typedef long long ll;

@interface Pair : NSObject
@property (nonatomic, assign) ll first;
@property (nonatomic, assign) int second;
@end

// Pair.m
#import "Pair.h"
@implementation Pair
@end

存储与取值

NSMutableArray *pairArray = [NSMutableArray array];

// 创建对象并赋值
Pair *pair1 = [[Pair alloc] init];
pair1.first = 123LL;
pair1.second = 45;
[pairArray addObject:pair1];

// 取出直接访问属性
Pair *retrievedPair = pairArray[0];
NSLog(@"First: %lld, Second: %d", retrievedPair.first, retrievedPair.second);

排序(对应C++ vector的排序)

用sortUsingComparator:方法,通过block自定义排序规则(比如按first升序,first相同则按second升序):

[pairArray sortUsingComparator:^NSComparisonResult(Pair *obj1, Pair *obj2) {
    if (obj1.first != obj2.first) {
        return obj1.first > obj2.first ? NSOrderedDescending : NSOrderedAscending;
    } else {
        return obj1.second > obj2.second ? NSOrderedDescending : NSOrderedAscending;
    }
}];

方案2:使用NSDictionary(快速实现,无需自定义类)

如果不想写额外的类,可以用字典存储键值对,缺点是类型不够安全(需要手动转换类型):

NSMutableArray *pairArray = [NSMutableArray array];

// 存储字典
NSDictionary *pairDict1 = @{@"first": @(123LL), @"second": @(45)};
[pairArray addObject:pairDict1];

// 取出并转换类型
NSDictionary *retrievedDict = pairArray[0];
ll first = [retrievedDict[@"first"] longLongValue];
int second = [retrievedDict[@"second"] intValue];
NSLog(@"First: %lld, Second: %d", first, second);

排序

同样用sortUsingComparator::

[pairArray sortUsingComparator:^NSComparisonResult(NSDictionary *d1, NSDictionary *d2) {
    ll f1 = [d1[@"first"] longLongValue];
    ll f2 = [d2[@"first"] longLongValue];
    if (f1 != f2) {
        return f1 > f2 ? NSOrderedDescending : NSOrderedAscending;
    } else {
        int s1 = [d1[@"second"] intValue];
        int s2 = [d2[@"second"] intValue];
        return s1 > s2 ? NSOrderedDescending : NSOrderedAscending;
    }
}];

总结

  • 如果追求类型安全和代码可读性,优先用自定义Objective-C类;
  • 临时快速实现可以用NSDictionary;
  • 坚持用结构体的话,务必记住用NSValue包装/还原的步骤。

内容的提问来源于stack exchange,提问作者user6298177

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:13:25