Предупреждение: «Отправка 'NSObject *' параметру несовместимого типа 'id‹NSCopying›'

Я поражен этим предупреждением в течение многих часов ... Я получаю

Код,

-(NSMutableDictionary*)iOSDiction
        {
            NSMutableDictionary *tmpDic = [[NSMutableDictionary alloc] initWithCapacity:[m_coordDic count]];
            for (NSObject *key in [m_coordDic allKeys]) 
            {
                [tmpDic setObject:[m_coordDic objectForKey:key] forKey:key];  //Warning
            }
            return tmpDic;
        }

Предупреждение:

"Отправка "NSObject *" в параметр несовместимого типа "id"

Передача аргумента параметру aKey здесь

NSDictionary.h

- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;

person AC Mohan    schedule 31.01.2014    source источник


Ответы (4)


Ключи NSDictionary должны соответствовать протоколу NSCopying. Это основное требование к ключу, как указано в NSDictionary. В общем, NSObject не соответствует протоколу (может быть, его подклассы), поэтому вы получаете предупреждение. Правильный способ сделать это

NSMutableDictionary *tmpDic = [[NSMutableDictionary alloc] initWithCapacity:[m_coordDic count]];
for (NSObject<NSCopying> *key in [m_coordDic allKeys]) 
{
    [tmpDic setObject:[m_coordDic objectForKey:key] forKey:key];  //Warning
}
return tmpDic;

Это гарантирует, что ваш ключ является любым объектом, подтверждающим протокол NSCopying.

РЕДАКТИРОВАТЬ: Кажется, что вы действительно пытаетесь сделать, это просто [m_coordDic mutableCopy], мелкая копия. Есть ли причина, по которой вы этого не делаете?

person Roshan    schedule 31.01.2014

NSObject не соответствует NSCopying. Вводя переменную как NSObject, вы сообщаете компилятору, что на любые сообщения, которые вы отправляете через эту переменную, отвечает NSObject. Поскольку NSObject не соответствует NSCopying, вы получаете это сообщение об ошибке.

Если вы пытаетесь сообщить компилятору, что переменная является каким-то объектом, но не имеет значения тип, вы должны ввести ее как id. Так:

for (id key in m_coordDic)

(Кстати, вам не нужны allKeys. Быстрое перечисление уже перечисляет ключи.)

person Chuck    schedule 31.01.2014
comment
В идеале вы хотите for (id<NSCopying> in ...). - person rmaddy; 31.01.2014
comment
@rmaddy: Может быть, это просто мое время сна, но почему это более идеально? Я не понимаю, как это когда-нибудь изменит ситуацию. - person Chuck; 31.01.2014
comment
Лично я нахожу это немного более самодокументированным. Это разъясняет необходимость ключа. - person rmaddy; 31.01.2014

Ключи NSDictionary должны соответствовать протоколу NSCopying. Вот что означает id<NSCopying>.

Очевидно, вы уже работаете с ключами NSDictionary, которые соответствуют NSCopying, но вы объявили переменную key как NSObject*, которая сама по себе не соответствует NSCopying.

Вам нужно объявить, что key действительно соответствует NSCopying. Вы можете сделать это с помощью NSObject<NSCopying>* key; однако многие люди вместо этого использовали бы id.

id — это специальный тип, который указывает компилятору пропускать любую проверку типов. В таком простом случае использование id обычно нормально:

for (id key in [myDictionary allKeys])
{
    // etc...
}
person Darren    schedule 31.01.2014

Это связано с несовместимым назначением. Поэтому вы должны использовать Particular object type или id--> for any instances of object.

Попробуй это :

 for (id key in [arr allKeys])
    {
        [tmpDic setObject:[m_coordDic objectForKey:key] forKey:key];  //Warning
    }
person Kumar KL    schedule 31.01.2014
comment
Сначала я проголосовал против, потому что первоначальный ответ был неправильным (что-то о том, как вы не должны передавать указатель). Затем вы отредактировали, и я попытался удалить отрицательный голос, но SO не позволяет мне. - person Chuck; 31.01.2014
comment
@Chuck Спасибо, да, мое предположение было неверным (объяснение). Поэтому я удалил только эту часть. AnyHow спасибо за ваше предложение. - person Kumar KL; 31.01.2014