Ric*_*ich 138 generics collections objective-c strong-typing data-structures
我是Mac/iPhone编程和Objective-C的新手.在C#和Java中,我们有"泛型",集合类的成员只能是声明的类型.例如,在C#中
Dictionary<int, MyCustomObject>
只能包含整数和值为MyCustomObject类型的键.Objective-C中是否存在类似的机制?
Con*_*nor 210
在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 *'
Run Code Online (Sandbox Code Playgroud)
在Swift代码中,它们会产生编译错误:
var str: String = arr[0]
var num: Int = arr[0] //Error 'String' is not convertible to 'Int'
Run Code Online (Sandbox Code Playgroud)
Lightweight Generics旨在与NSArray,NSDictionary和NSSet一起使用,但您也可以将它们添加到您自己的类中:
@interface GenericsTest<__covariant T> : NSObject
-(void)genericMethod:(T)object;
@end
@implementation GenericsTest
-(void)genericMethod:(id)object {}
@end
Run Code Online (Sandbox Code Playgroud)
Objective-C的行为与之前的编译器警告一样.
GenericsTest<NSString*>* test = [GenericsTest new];
[test genericMethod:@"string"];
[test genericMethod:@1]; // Warning: Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'
Run Code Online (Sandbox Code Playgroud)
但Swift将完全忽略通用信息.(在Swift 3+中不再适用.)
var test = GenericsTest<String>() //Error: Cannot specialize non-generic type 'GenericsTest'
Run Code Online (Sandbox Code Playgroud)
除了这些Foundation集合类之外,Swift还忽略了Objective-C轻量级泛型.使用轻量级泛型的任何其他类型都会导入到Swift中,就好像它们是未参数化的一样.
Mar*_*c W 91
这个答案已经过时但仍具有历史价值.从Xcode 7开始,Connor在2015年6月8日的回答更为准确.
不,除非您想在自己的自定义集合类中使用C++模板,否则Objective-C中没有泛型(我强烈反对).
Objective-C将动态类型作为一个特性,这意味着运行时不关心对象的类型,因为所有对象都可以接收消息.将对象添加到内置集合时,它们只是被视为类型id.但不要担心,只需像正常那样向这些对象发送消息; 它会正常工作(当然,除非集合中的一个或多个对象不响应您发送的消息).
Java和C#等语言需要泛型,因为它们是强大的静态类型语言.与Objective-C的动态打字功能完全不同的球赛.
小智 11
不,但为了使它更清晰,你可以用你想要存储的对象类型来评论它,我已经看到这样做了几次,当你需要在Java 1.4中编写一些东西时,例如:
NSMutableArray* /*<TypeA>*/ arrayName = ....
Run Code Online (Sandbox Code Playgroud)
要么
NSDictionary* /*<TypeA, TypeB>*/ dictionaryName = ...
Run Code Online (Sandbox Code Playgroud)
Apple在XCode 7中为ObjC添加了泛型:
@property NSArray<NSDate *>* dates;
- (NSArray<NSDate *> *)datesBeforeDate:(NSDate *)date;
- (void)addDatesParsedFromTimestamps:(NSArray<NSString *> *)timestamps;
Run Code Online (Sandbox Code Playgroud)
请参阅此处:https: //developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/uid/TP40014216-CH6-ID61
这是在Xcode 7中发布的(最后!)
请注意,在Objective C代码中,它只是一个编译时检查; 只有将错误的类型放入集合或分配给类型属性才会出现运行时错误.
宣布:
@interface FooClass <T> : NSObject
@property (nonatomic) T prop;
@end
Run Code Online (Sandbox Code Playgroud)
使用:
FooClass<NSString *> *foo = [[FooClass alloc] init];
NSArray<FooClass<NSString *> *> *fooAry = [NSArray array];
Run Code Online (Sandbox Code Playgroud)
小心那些*.