在NSArray上使用下标时编译错误"找不到预期的方法"

Ben*_*ove 33 cocoa compiler-errors objective-c nsarray objective-c-literals

我编写了这个简单的代码来试用NSArrays 的新Objective-C文字语法:

NSArray *array = @[@"foo"];
NSLog(@"%@", array[0]); 
Run Code Online (Sandbox Code Playgroud)

第一行工作正常,但下标导致错误:

读取在'NSArray*'类型的对象上找不到的数组元素的预期方法

只是想知道我是否做错了什么,或者文字还没有完全实现.我正在使用Apple LLVM 4.0编译并使用iOS 5 SDK.

这里也是错误的屏幕截图.

错误

Jos*_*ell 36

您必须使用iOS 6或OS X 10.8 SDK进行编译 - 否则Foundation对象没有必要的方法来使用文字语法的下标位.*特别是在这种情况下,下标期望objectAtIndexedSubscript:通过以下方式实现:NSArray,这是为与此编译器功能交互而创建的新方法.与语句创建有关的新语法部分应该可以正常工作 - 我不相信需要任何新方法.

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


*我基于borrrden进行的一些研究:https://stackoverflow.com/a/11407844/603977

我已经得到了很多关于这个答案的赞成,我真的觉得这是建立在borrrden的基础之上的.如果您认为我的答案值得投票,请点击并在那里投票.

  • 我想提醒一件小事.因此,也不支持文字布尔.但是,我实现的快速修复是将其添加到我的一个常见标题的开头(在iOS项目中) - >`#ifndef __IPHONE_6_0 #if __has_feature(objc_bool)#undef是#undef否#define是__objc_yes #define没有__objc_no #endif #endif` (2认同)

Aar*_*man 15

如果您不是针对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上实现下标,您只需实现:

- (id) objectAtIndexedSubscript:(NSUInteger)index{
    return [self objectAtIndex:index];
}
Run Code Online (Sandbox Code Playgroud)

我能看到的唯一缺点是你需要确保将你的类别导入任何打算使用下标的类.当然,您可以通过#import在前缀标题中包含通常文件来解决该要求:<appname>-Prefix.pch.(感谢Josh Caswell指出这一点).

一个好处是你可以改变下标方法以满足你的需求.例如,Apple不允许您使用下标向NSMutableArray添加/删除对象,但这可以很容易地完成:

 - (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];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 好的,但值得补充一点,你不需要这样做*目标*iOS5,只需要*编译*与早期的SDK.您可以定位iOS5(并使用新的构造)并使用iOS6 sdk进行编译. (6认同)