Objective-C 泛型不适用于方法? (Xcode 7 测试版(内部版本:7A120f))

Objective-C generics not working for methods? (Xcode 7 Beta (build: 7A120f))

所以,很明显,在 WWDC 之后,我正在玩上周展示的新东西。如您所知,Apple 将泛型引入了 Objective-C

的世界

Note: This answer is somehow follow-up to this question: Are there strongly-typed collections in Objective-C?

我在方法中尝试了这段代码,效果很好

NSMutableArray<NSString*> *array = [[NSMutableArray alloc] init];

[array addObject:@""];
[array addObject:@(54)];Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString * __nonnull'
// Great, generics works as expected.

但是我也有方法想转换成泛型

在头文件中:

- (NSArray <NSString*> *)objectsToSearch;

实施:

- (NSArray <NSString*> *)objectsToSearch
{
    NSString *first = @"1";

    NSString *second = @"2";

    NSString *third = @"3";

    NSNumber *test = @(55);

    return @[first, second, third, test]; // No-error!!!
}

我是不是做错了什么,或者 Clang 不支持泛型 + 文字,还是我还遗漏了什么?

我同意这是一个错误。我测试了你案例的一个更简单的版本,但它仍然失败。

NSString *first = @"1";
NSString *second = @"2";
NSString *third = @"3";
NSNumber *test = @(55);

NSArray <NSString*>* arr  = @[first, second, third, test, @(20)];

这似乎也不是数组文字语法的问题。该行仍然没有产生错误。

NSArray <NSString*>* anotherArray = [NSArray arrayWithObjects:first, second, third, test, @(20), nil];

不要假设 Apple 正在向 Obj-C 添加泛型,因为他们想要改进 Obj-C。真正的原因是所有 iOS/OS 用 Obj-C 编写的 X 框架都很难在 Swift 中使用 - 你必须从 AnyObject.

中转换所有内容

向 Obj-C 添加泛型使 Apple 能够正确标记方法,例如

@property(nonatomic, readonly, copy) NSArray <__kindof UIView *> *subviews

重要的是现在 Swift 可以更好地使用框架。实施 warnings/errors 以防止在 Obj-C 中滥用泛型并不那么重要,因此我们可以预期那里会出现很多错误。

我建议您报告错误,但不要指望它会很快得到修复。

我刚刚遇到这个 post,但我没有得到相同的结果。我已将代码剪切并粘贴到 XCode 中以确认,上面的所有示例都会产生错误(我将警告设置为错误)。所以我没有看到错误。要么是那个,要么是编译器设置在我们之间不同。

我刚刚对此进行了更多诊断,我不认为这是一个错误。下面的代码显示了各种选项以及每个选项为什么会或不会编译。 注意:这是基于我对事情如何运作的猜测。 Apple 的解释可能会有所不同。

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
-(void) testGenericArrays {

    NSString *aString = @"abc";
    NSNumber *aNumber = @(55);

    NSArray<NSString *> *arr1  = @[aString, aNumber];
    // Compiles because the RHS is an un-typed array at compilation time.

    NSArray<NSString *> *arr2  = @[aString, @(20)];
    // Compiles because the RHS is an un-typed array at compilation time.

    NSArray<NSString *> *arr3 = [NSArray<NSString *> arrayWithObjects:aString, aNumber, @(20), nil];
    // Compiles because the type erasure for arrayWithObjects only types the first argument which is a NSString.
    // The rest of the arguments are a vaList which is not checked during header processing.

    NSArray<NSString *> *arr4 = [NSArray<NSString *> arrayWithObjects:@(20), nil]; // <- Error!
    NSArray<NSString *> *arr5 = [NSArray<NSString *> arrayWithObjects:aNumber, nil]; // <- Error!
    // Neither of these two compile because the first argument is now a NSNumber and is checked.

    NSArray<NSString *> *arr6 = [NSArray<NSString *> arrayWithObject:aNumber]; // <- Error!
    // Doesn't compile because the argument is checked during header processing.

    NSArray<NSString *> *arr7 = [NSArray arrayWithObject:aNumber];
    // Compiles because the RHS is an un-typed array at compilation time.

    NSMutableArray<NSString *> *arr8 = [[NSMutableArray alloc] init];
    [arr8 addObject:aNumber]; // <- Error!
    // Doesn't compile because the LHS is a typed array and we are adding to it.
}
#pragma clang diagnostic pop

希望这能为人们澄清一些事情。随意剪切并粘贴到单元测试中并亲自尝试一下。