Ошибка компилятора «ожидаемый метод не найден» при использовании индекса на NSArray

Я написал этот простой код, чтобы опробовать новый синтаксис Objective-C дляNSArrays:

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

Первая строка работает нормально, но подписка приводит к ошибке:

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

Просто интересно, сделал ли я что-то не так, или литералы еще не полностью реализованы. Я компилирую с помощью Apple LLVM 4.0 и использую iOS 5 SDK.

Вот и скриншот ошибки.

Error

 Josh Caswell11 июл. 2012 г., 08:38
Вы также должны компилироваться с SDK для iOS 6 или OS X 10.8 - в противном случае у объектов Foundation нет необходимых методов для подписывания бита литерального синтаксиса.
 Ben Trengrove11 июл. 2012 г., 07:30
Да, я использую LLVM 4.0. Должен был упомянуть, что
 Ben Trengrove11 июл. 2012 г., 09:01
@JoshCaswell Вот ответ, я собираюсь на iOS5. Опубликовать как ответ, чтобы я мог принять!
 Paresh Navadiya11 июл. 2012 г., 09:12
 Alexis King11 июл. 2012 г., 07:30
На странице clang.llvm.org о литералах Objective-C указано, что для использования новых функций необходимо использовать Apple LLVM 4.0 или clang v3.1. У вас установлен один из них, и указан ли он в настройках вашей сборки?

Ответы на вопрос(7)

добавлять #import <Foundation/Foundation.h> в ваш файл h, и используйтеNSMutableArray вместо

Решение Вопроса

случае объекты Foundation не имеют необходимых методов для подписывания бита буквального синтаксиса. * В частности, в этом случае ожидание подписки ожидаетсяobjectAtIndexedSubscript: быть реализованнымNSArrayи это новый метод, который был создан для взаимодействия с этой функцией компилятора. Части нового синтаксиса, которые имеют отношение только к созданию объектов, должны работать нормально, хотя я не верю, что для этого требуются какие-либо новые методы.

Дальнейшее чтение наhttp://clang.llvm.org/docs/ObjectiveCLiterals.html

* Я основываю это на небольшом исследовании, выполненном Borrrden:https://stackoverflow.com/a/11407844/603977

I've gotten a lot of upvotes on this answer, which I really feel is founded on borrrden's. Please, if you think my answer is worth an upvote, click through and vote there too.

 26 июл. 2012 г., 10:42
Есть одна маленькая вещь, о которой я хотел бы предупредить. Литеральные bools также не поддерживаются из-за этого. Однако быстрое исправление, которое я реализовал, добавило это в начало одного из моих общих заголовков (в проекте iOS) - & gt;#ifndef __IPHONE_6_0 #if __has_feature(objc_bool) #undef YES #undef NO #define YES __objc_yes #define NO __objc_no #endif #endif
 10 авг. 2012 г., 21:26
Это хороший вопрос, @Jonathan.
 10 авг. 2012 г., 21:10
почему подписка не ссылается только на objectAtIndex (если objectAtIndexedSubscript не найден или только на -iOS6)?
 17 апр. 2013 г., 15:14
Начиная с Xcode 4.4, новый синтаксис будет по-прежнему развертываться обратно на iOS 5, вызывая objectAtIndex :. Ваша цель развертывания должна быть правильно установлена на 5.0, а SDK - на самую последнюю версию. Увидетьdeveloper.apple.com/library/ios/#releasenotes/ObjectiveC/… для матрицы совместимости.

в Xcode 9.3 beta 4 с каким-то устаревшим кодом Objective-C, как я, то здесь было мое исправление.

Обновить:

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

Для того, чтобы:

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

потому что это распространенная ошибка, которая все еще существует в XCode по состоянию на 7/2015, и не легко понять, как ее решить.

Я получил эту ошибку при попытке вызвать метод объекта, не создавая экземпляр объекта. Мое решение состояло в том, чтобы создать экземпляр объекта, а затем вызвать метод для свойства в экземпляре этого объекта.

Пример: Что не сработало:[self methodCall:arrayItem] (см. полный пример ниже)

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

Что это исправило: ObjectClass newObject = arrayItem; [self methodCall:newObject] (see full example below)

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

я хотел бы отметить, что заставить подписку работать по-прежнему удивительно легко. Все, что вам нужно сделать, это добавить необходимые методы в качестве категории, для которой будут работать подписки, и реализовать эти методы соответствующим образом. Поэтому добавьте в следующие классы методы:

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];
    }
}
 01 авг. 2012 г., 08:34
Очень хороший трюк.
 04 авг. 2012 г., 03:38
Это правда, но на данный момент iOS 6 является только бета-версией. Не особенно полезно для производственного кода. Конечно, через месяц или около того точка будет немой.
 26 июл. 2012 г., 13:56
Спасибо @JoshCaswell! Я забыл о префиксе. Я отредактировал пост, чтобы включить вашу информацию.
 26 июл. 2012 г., 08:45
& # xAB; вам нужно обязательно импортировать свою категорию в любой класс, который намеревается использовать подписку & # xBB; Там нет проблем; просто поместите его в заголовок вашего префикса! Хороший пост!
 01 авг. 2012 г., 08:54
Хороший вопрос, но стоит добавить, что вам не нужно делать это, чтобыtarget iOS5, только дляcompile с более ранним SDK. Вы можете настроить iOS5 (и использовать новые конструкции) и скомпилировать с iOS6 SDK.

эта ссылка:

Вы можете просто добавить эту категорию в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.

 26 авг. 2012 г., 15:42
Это работает очень хорошо и очень просто по сравнению с другими ответами. Спасибо!
 20 сент. 2012 г., 22:15
Это хороший момент. Использование @optional было бы хорошей идеей. Конечно, Xcode 4.5 официально выпущен сейчас, и все это больше не нужно.
 18 сент. 2012 г., 18:43
Чем это отличается от ответа Аарона?
 20 сент. 2012 г., 19:27
Я пропустил, что это категория наNSObjectи я должен сказать, что мне это не нравится. Таким образом, категория будет реализована на объектах, для которых методы не имеют значения. Была особенность языка (@optional методы протокола), введенные некоторое время назад, чтобы избежать именно этого. Методы должны быть добавлены в классы, где они необходимы.
 19 сент. 2012 г., 00:28
Его ответ предлагает создать несколько категорий. Это более простой способ, так как вам нужно всего лишь создать одну категорию. Хотя это может быть очевидным для опытных разработчиков, это, вероятно, будет менее очевидно для разработчиков, которые плохо знакомы с категориями.

но тогда это было не из-за отсутствия версии для iOS ... но это было просто потому, что исходный массив был установлен какNSArray а неNSMutableArray, Меняя его наNSMutableArray исправил это для меня

Ваш ответ на вопрос