NS_STRING_ENUM - ShenYj/ShenYj.github.io GitHub Wiki
在 Xcode 8 中,苹果为 Objective-C 提供了全新的 Macro
: NS_STRING_ENUM
和 NS_EXTENSIBLE_STRING_ENUM
,让这些字串常量使用起來更像是 Swift 原生的 string enum。
Apple 建议弃用
NS_STRING_ENUM/NS_EXTENSIBLE_STRING_ENUM
而改用NS_TYPED_ENUM/NS_TYPED_EXTENSIBLE_ENUM
,本质上都一样, 就是一套旧的一套新的
-
目前在最新的 SDK 中,无论你使用那种方式来定义,最终都是
NS_TYPED_ENUM
与NS_TYPED_EXTENSIBLE_ENUM
// Note: NS_TYPED_ENUM is preferred to NS_STRING_ENUM #define NS_STRING_ENUM _NS_TYPED_ENUM // Note: NS_TYPED_EXTENSIBLE_ENUM is preferred to NS_EXTENSIBLE_STRING_ENUM #define NS_EXTENSIBLE_STRING_ENUM _NS_TYPED_EXTENSIBLE_ENUM #define NS_TYPED_ENUM _NS_TYPED_ENUM #define NS_TYPED_EXTENSIBLE_ENUM _NS_TYPED_EXTENSIBLE_ENUM
NS_STRING_ENUM
需要搭配 typedef
使用。
-
OCClass.h
#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN typedef NSString * Week NS_STRING_ENUM; FOUNDATION_EXPORT Week const WeekMonday; FOUNDATION_EXPORT Week const WeekTuesday; FOUNDATION_EXPORT Week const WeekWendesday; FOUNDATION_EXPORT Week const WeekThursday; FOUNDATION_EXPORT Week const WeekFriday; FOUNDATION_EXPORT Week const WeekSaturday; FOUNDATION_EXPORT Week const WeekSunday; @interface OCClass : NSObject + (void)test_OCStringEnumFunc:(Week)week; @end NS_ASSUME_NONNULL_END
-
OCClass.m
#import "OCClass.h" NSString * const WeekMonday = @"WeekMonday"; NSString * const WeekTuesday = @"WeekTuesday"; NSString * const WeekWendesday = @"WeekWendesday"; NSString * const WeekThursday = @"WeekThursday"; NSString * const WeekFriday = @"WeekFriday"; NSString * const WeekSaturday = @"WeekSaturday"; NSString * const WeekSunday = @"WeekSunday"; @implementation OCClass + (void)test_OCStringEnumFunc:(Week)week { NSLog(@"%@", week); } @end
-
OC 内使用
本质上还是一个别名,如图所示,我随意传递字符串是不会有任何报错的,不过在书写时还是提高了便利性,对具有指定的原始值类型的常量进行分组定义还是很不错的
-
Swift 混编中使用
public class SwiftClass: NSObject { @objc static func swiftFunc() { OCClass.test_OCStringEnumFunc(.friday) } }
如果 OC 中仍然使用
FOUNDATION_EXPORT NSString * const WeekMonday;
这种写法,那么在换到Swift中使用时也要使用WeekMonday
-
查看编译器为 Objective-C 接口自动生成的 Swift 接口
选中
OCClass.h
文件,点击左上角的Related Items
按钮,将光标移动到Generated Interface
那一栏,右边就会出现不同版本的 Swift 接口文件。选择一个点开后,就可以查看对应版本的 Swift 接口文件了
-
e.g.
OCClass.h (Swift 5 Interface)
import Foundation public struct Week : Hashable, Equatable, RawRepresentable { public init(rawValue: String) } extension Week { public static let monday: Week public static let tuesday: Week public static let wendesday: Week public static let thursday: Week public static let friday: Week public static let saturday: Week public static let sunday: Week } open class OCClass : NSObject { open class func test_OCStringEnumFunc(_ week: Week) }
-
-
在
Swift
中为其扩展新增值public extension Week { // NS_TYPED_ENUM static var freeDay: Week { Week(rawValue: "WeekFreeDay") } // NS_TYPED_EXTENSIBLE_ENUM //static var freeDay: Week { Week("WeekFreeDay") } }
-
在 OC 与 Swift 混编时带来的改善,可以阅读 字符串枚举