1. ホーム
  2. objective-c

[解決済み] Objective-Cには強い型付けのコレクションがありますか?

2022-05-13 17:15:15

質問

Mac/iPhone のプログラミングと Objective-C の初心者です。 C# と Java には、宣言された型にのみ対応するメンバーを持つコレクション クラス、quot;generics" があります。 たとえば、C#では

Dictionary<int, MyCustomObject>

は整数であるキーと MyCustomObject 型である値のみを含むことができます。 Objective-Cにも同じようなメカニズムがあるのでしょうか?

どのように解決するのですか?

Xcode 7 では、Apple は Objective-C に 'Lightweight Generics' を導入しました。Objective-C では、型の不一致がある場合、コンパイラーの警告を生成します。

NSArray<NSString*>* arr = @[@"str"];

NSString* string = [arr objectAtIndex:0];
NSNumber* number = [arr objectAtIndex:0]; // Warning: Incompatible pointer types initializing 'NSNumber *' with an expression of type 'NSString *'

そして、Swiftのコードでは、それらはコンパイラーエラーを発生させます。

var str: String = arr[0]
var num: Int = arr[0] //Error 'String' is not convertible to 'Int'

Lightweight Genericsは、NSArray、NSDictionary、NSSetで使用することを想定していますが、独自のクラスに追加することも可能です。

@interface GenericsTest<__covariant T> : NSObject

-(void)genericMethod:(T)object;

@end

@implementation GenericsTest

-(void)genericMethod:(id)object {}

@end

Objective-Cはコンパイラの警告で以前と同じような動作をします。

GenericsTest<NSString*>* test = [GenericsTest new];

[test genericMethod:@"string"];
[test genericMethod:@1]; // Warning: Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'

というように記述しますが、SwiftはGenericの情報を完全に無視します。(Swift3+ではもはや真ではありません)。

var test = GenericsTest<String>() //Error: Cannot specialize non-generic type 'GenericsTest'

これらの Foundation コレクションクラス以外では、Objective-C の軽量ジェネリックスは Swift では無視されます。軽量ジェネリックスを使用する他の型は、それらがパラメータ化されていないかのように、Swift にインポートされます。

Objective-CのAPIと対話する