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

如何在Objective-C中实现Swift协议的[String]类型属性?

问题描述

我需要在Objective-C中实现Swift协议定义的[String]类型数组属性。

Swift协议代码

@objc protocol MyProtocol {
    var myProperty: [String] { get }
}

Objective-C实现代码

@interface MyThing : NSObject <MyProtocol>

@property (readonly, copy, nonnull) NSArray* myProperty;

- (_Nonnull instancetype)init;

@end

@implementation MyThing

- (instancetype)init {
    self = [super init];
    return self;
}

- (NSArray*)myProperty {
    return @[@"A value"];
}

@end

目前遇到的问题:Objective-C中使用NSArray*,在Swift里会被解析为[Any]类型而非[String],导致Swift中使用MyThing类时,编译器认为协议属性未实现。

请问有没有办法提示编译器该数组为字符串数组?或者让Swift隐式将[Any]数组包装为[String]数组?

我目前想到两种不太理想的解决办法:

  • 创建一个封装[String]数组的Swift类,用该类作为协议属性类型。缺点是若想让该类型无需拆箱即可像数组一样工作,必须实现所有数组方法。
  • 定义一个Objective-C可重写的内部属性getter(类型为[Any]),再添加一个将结果转为字符串数组的便利属性。但这种方式会牺牲类型安全性。

解决方案

直接在Objective-C的属性声明和方法返回值中,使用*带泛型约束的NSArray<NSString *> **来替代NSArray*,就能让Swift自动识别为[String]类型,完美匹配协议要求。

修改后的Objective-C代码如下:

@interface MyThing : NSObject <MyProtocol>

@property (readonly, copy, nonnull) NSArray<NSString *>* myProperty;

- (_Nonnull instancetype)init;

@end

@implementation MyThing

- (instancetype)init {
    self = [super init];
    return self;
}

- (NSArray<NSString *>*)myProperty {
    return @[@"A value"];
}

@end

原理说明

Objective-C 2.0开始支持泛型语法,NSArray<NSString *>明确告知编译器该数组的元素均为NSString类型。Swift与Objective-C交互时,会自动将带泛型约束的NSArray<NSString *>桥接为[String],完全符合Swift协议中myProperty: [String]的类型要求,编译器也不会再报错。

这种方法无需额外封装类,也不会牺牲类型安全性,是最直接且优雅的解决方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 07:33:20