Предупреждение: „Изпращане на „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)

(BTW, нямате нужда от 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