关于C#:在NSArray上使用下标时编译器错误“找不到预期的方法”

Compiler error “expected method not found” when using subscript on NSArray

我编写了这段简单的代码来尝试NSArray的新的Objective-C文字语法:

1
2
NSArray *array = @[@"foo"];
NSLog(@"%@", array[0]);

第一行工作正常,但订阅会导致错误:

Expected method to read array element not found on object of type 'NSArray *'

只是想知道我是否做错了什么,或者文字是否还没有完全实现。我正在使用Applellvm4.0和iOS5sdk进行编译。

这也是错误的屏幕截图。

Error


您必须使用IOS 6或OS X 10.8 SDKS编译否则基础设施没有必要的方法来标示文字语法。*在这种情况下,下标期望EDOCX1 0 0由EDCOX1§1实现,这是一种创建与该编译器交互的新方法。埃克斯但是,新语法中与对象创建相关的部分应该可以很好地工作——我认为这不需要任何新方法。

进一步阅读http://clang.llvm.org/docs/objectiveecliterals.html

*我基于Borrrden的一点研究:https://stackoverflow.com/a/11407844/603977

我在这个答案上得到了很多赞成票,我真的觉得这是建立在Borrrden的基础上的。请,如果你认为我的答案值得一个赞成票,点击并在那里投票。


如果你的目标不是iOS 6或OS X 10.8,我想指出订阅工作仍然非常容易。您所要做的就是将所需方法添加为您想要订阅的类所适用的类别,并适当地实现这些方法。因此,将方法添加到以下类中:

NSArray- (id)objectAtIndexedSubscript: (NSUInteger)index;

NSMutableArray- (void)setObject: (id)obj atIndexedSubscript: (NSUInteger)index;

NSDictionary- (id)objectForKeyedSubscript: (id)key;

NSMutableDictionary- (void)setObject: (id)obj forKeyedSubscript: (id)key;

实现这一点很简单,只需为类调用适当的方法。例如,要在nsarray上实现订阅,只需实现:

1
2
3
- (id) objectAtIndexedSubscript:(NSUInteger)index{
    return [self objectAtIndex:index];
}

我能看到的唯一缺点是,您需要确保将您的类别导入到任何打算使用订阅的类中。当然,通过在前缀头中包含#import,您可以绕过这个要求,通常是文件:-Prefix.pch。(感谢乔希·卡斯韦尔指出这一点)。

一个好处是您可以更改订阅方法以满足您的需要。例如,Apple不允许您使用订阅向NSmutableArray添加/删除对象,但这可以很容易地做到:

1
2
3
4
5
6
7
8
9
10
 - (void) setObject:(id)obj atIndexedSubscript:(NSUInteger)index{
    if (index < self.count){
        if (obj)
            [self replaceObjectAtIndex:index withObject:obj];
        else
            [self removeObjectAtIndex:index];
    } else {
        [self addObject:obj];
    }
}


我从这个链接得到了以下代码:

您只需将这个类别添加到NSObject中,就可以订阅集合。我把它放在我的.pch文件中。

1
2
3
4
5
6
7
8
9
10
11
// Add support for subscripting to the iOS 5 SDK.
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 60000
@interface NSObject (SubscriptingSupport)

- (id)objectAtIndexedSubscript:(NSUInteger)idx;
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;
- (id)objectForKeyedSubscript:(id)key;

@end
#endif

当然,您需要最新版本的clang,它已经在xcode 4.4中了。


我也遇到了同样的问题,但那不是缺少iOS版本的B/C。但这仅仅是因为原始数组被设置为NSArray,而不是NSMutableArray。改成NSMutableArray给我修了


添加在你的H文件中,用一个NSMutableArray代替。


我添加这个是因为这是一个常见的错误,到2015年7月Xcode中仍然存在,并且不容易找到解决方法。

我在没有创建对象实例的情况下尝试对对象调用方法时收到此错误。我的解决方案是创建对象的实例,然后对该对象实例的属性调用方法。

例子:不起作用的内容:【self-methodcall:arrayItem】(请参阅下面的完整示例)

1
[self tappedUser:self.activities[indexPath.row].followItem.user.givenName];

什么固定了它:objectclass newobject=arrayitem;[自我方法调用:NewObject](见下面的完整示例)

1
2
FollowActivityItem *followItem = self.activities[indexPath.row];
[self tappedUser:followItem.user.givenName];


如果有人在Xcode9.3测试版4中使用一些与我一样的遗留的Objective-C代码获得了这个错误之后访问了这个旧线程,那么这里是我的修复方法。

更新:

1
@property (nonatomic, strong) id<CustomClass> myObject;

到:

1
@property (nonatomic, strong) NSMutableArray<CustomClass> *myObject;