переменная типа id

#objective-c #xcode #sprite-kit

#objective-c #xcode #набор спрайтов

Вопрос:

У меня есть этот код для добавления узлов спрайтов препятствий в качестве дочерних элементов к concreteGround узлу:

 -(void) addObstaclesToNode:(NSString *)pattern
{
    for(int index = 0; index<[self getPattern:pattern].arrayOfSprites.count;   index)
    {
        id o = [[self getPattern:pattern].arrayOfSprites objectAtIndex:index];
        o.position = CGPointMake(o.position.x   windowW, o.position.y);
        [concreteGround addChild:[[self getPattern:pattern].arrayOfSprites objectAtIndex:index]];
    }
}
  

( getPattern это метод, который я создал для возврата объекта в массив) В любом случае, я хочу, чтобы переменная o получала [[self getPattern:pattern].arrayOfSprites objectAtIndex:index] , но этот код может возвращать объекты разных типов. Раньше я id делал это, но когда я пытаюсь получить доступ к свойству объекта, Xcode сообщает мне, что «свойство не было найдено для объекта с типом id». Я делаю что-то не так? Спасибо за помощь…

Ответ №1:

К вашему Q:

В Objective-C царит большой хаос, связанный с объявленными свойствами. (Латтнер был там?)

Что касается точечной записи, то даже в ней ничего не говорится о способе реализации свойства и его средств доступа (синтезировать или явно) и декларировании (@property или объявления метода), компилятор не принимает никакого известного свойства, а только свойства объектов с известным типом.

Вы можете сделать две вещи:

  1. Не используйте точечную нотацию для доступа. (Это допустимо, если метод объявлен где угодно.)

  2. Понизьте значение объекта.

Кстати: Ваш код не очень объективен. Вы можете использовать быстрое перечисление и индексированную подписку, чтобы сделать ее лучше читаемой.

Ответ №2:

Да, вам нужно убедиться, что o является экземпляром класса, который поддерживает этот селектор, или что он поддерживает селектор.

 if ([o isKindOfClass:[YCYourClass class]]) {
    YCYourClass *yourClass = o;
    yourClass.position = ...
}
  

Или:

 if ([o respondsToSelector:@selector(setPosition:)]) {
    [o performSelector...
}
  

Хотя, теперь, когда я думаю об этом, вы, возможно, просто забыли включить заголовок, в котором вы объявляете интерфейс с position селектором … это тоже может сработать.