Ошибка компилятора "ожидаемый метод не найден" при использовании индекса на NSArray
Я написал этот простой код, чтобы опробовать новый синтаксис Objective-C для NSArray
s:
NSArray *array = @[@"foo"];
NSLog(@"%@", array[0]);
Первая строка работает нормально, но подписка приводит к ошибке:
Ожидаемый метод для чтения элемента массива, не найденного в объекте типа 'NSArray *'
Просто интересно, сделал ли я что-то не так, или литералы еще не полностью реализованы. Я компилирую с Apple LLVM 4.0 и использую iOS 5 SDK.
Вот скриншот ошибки тоже.
8 ответов
Вы должны компилироваться с SDK для iOS 6 или OS X 10.8 - в противном случае объекты Foundation не имеют необходимых методов для подписывания бита литерального синтаксиса.* В частности, в этом случае для подписки требуется objectAtIndexedSubscript:
быть реализованным NSArray
и это новый метод, созданный для взаимодействия с этой функцией компилятора. Части нового синтаксиса, которые имеют отношение только к созданию объектов, должны работать нормально - я не верю, что для этого нужны какие-либо новые методы.
Дополнительную информацию читайте на http://clang.llvm.org/docs/ObjectiveCLiterals.html
* Я основываю это на небольшом исследовании, выполненном borrrden: /questions/14833691/mozhno-li-ispolzovat-llvm-40-v-xcode-43/14833705#14833705
Я получил много откликов по этому ответу, который, на мой взгляд, основан на ответе Борррдена. Пожалуйста, если вы считаете, что мой ответ стоит лишнего голоса, нажмите и проголосуйте там же.
Если вы не ориентируетесь на 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];
}
Единственный недостаток, который я вижу, это то, что вам нужно обязательно импортировать свою категорию в любой класс, который намеревается использовать подписку. Конечно, вы можете обойти это требование, включив #import
в заголовке вашего префикса обычно файл: <appname>-Prefix.pch
, (спасибо Джошу Касвеллу за то, что указал на это).
Одним из преимуществ является то, что вы можете изменить методы подписки в соответствии со своими потребностями. Например, 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];
}
}
Я получил следующий код по этой ссылке:
Вы можете просто добавить эту категорию в NSObject
и сбор подписки будет работать. Я положил его в мой файл.pch.
// 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... но это было просто потому, что исходный массив был установлен как NSArray
а не NSMutableArray
, Меняя его на NSMutableArray
исправил это для меня
Я добавляю это, потому что это распространенная ошибка, которая все еще существует в XCode по состоянию на 7/2015, и нелегко понять, как ее решить.
Я получил эту ошибку при попытке вызвать метод объекта, не создавая экземпляр объекта. Мое решение состояло в том, чтобы создать экземпляр объекта, а затем вызвать метод свойства для экземпляра этого объекта.
Пример: что не сработало: [self methodCall: arrayItem] (см. Полный пример ниже)
[self tappedUser:self.activities[indexPath.row].followItem.user.givenName];
Что это исправило: ObjectClass newObject = arrayItem; [self methodCall: newObject] (см. полный пример ниже)
FollowActivityItem *followItem = self.activities[indexPath.row];
[self tappedUser:followItem.user.givenName];
Добавлять #import <Foundation/Foundation.h>
в ваш файл h, и используйте NSMutableArray
вместо
Получите эту ошибку для некоторого глупого конфликта именования:
NSInteger item = indexPath.item;
switch (item) {
//many lines of code
}
SongItem *item = self.datas[item]//this item is not the item of indexPath
Если кто-нибудь доберется до этой старой темы после получения этой ошибки в Xcode 9.3 beta 4 с каким-то устаревшим кодом Objective-C, как я, то здесь было мое исправление.
Обновить:
@property (nonatomic, strong) id<CustomClass> myObject;
Для того, чтобы:
@property (nonatomic, strong) NSMutableArray<CustomClass> *myObject;