Вопрос

Когда я попытался скомпилировать свое приложение для OS 3, я обнаружил следующую ошибку:

ошибка: тип средства доступа не соответствует типу свойства

Ошибка была для свойства, к которому я пытался получить доступ, которое определено следующим образом:

NSMutableArray *myArray

@property (readonly,nonatomic) NSArray* myArray;

свойство @synthesized в файле реализации.

Это прекрасно работало в OS 2.2.1, но не в OS 3.0

Написание метода get самостоятельно решило проблему.

Кто-нибудь знает об изменениях в target-c между ОС 2.2.1 и 3.0? Есть ли документация для этих изменений?

API документ изменений не содержит ничего об этой проблеме.

РЕДАКТИРОВАТЬ

ошибка возникает при попытке доступа к свойству, например,

NSArray *anArray = myClass.myArray;

Как я упоминал выше, я нашел обходной путь для этого: сам пишу метод getter, однако, что мне действительно нужно, так это какая-то документация от Apple, объясняющая это изменение и любые другие изменения, не связанные с API.

Спасибо за вашу помощь

Это было полезно?

Решение

Это ошибка компилятора.

Хотя вы не указали это полностью, я ожидаю, что ваш код выглядит следующим образом:

@interface Foo : NSObject {
    NSMutableArray *objects;
}
@property (readonly, copy) NSArray *objects;
@end

@implementation Foo
@synthesize objects;
@end

Компилятор, к сожалению, путается между объявлением objects property и объявлением objects экземпляра переменной . Помните, что свойства и переменные экземпляра - это разные вещи в Objective-C; свойство может быть поддержано переменной экземпляра, но оно действительно является частью открытого интерфейса класса.

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

@interface Foo : NSObject {
    NSMutableArray *_objects;
}
@property (readonly, copy) NSArray *objects;
@end

@implementation Foo
@synthesize objects = _objects;
@end

Таким образом, компилятор не запутывается в отношении свойства по сравнению с переменной экземпляра в выражениях, таких как self.objects (что в любом случае не следует, но, очевидно, так и есть).

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

Другие советы

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

<Ч>

Обратите внимание, что даже если вы объявите тип свойства как NSArray , возвращаемый объект по-прежнему будет NSMutableArray , а изменяемые методы являются определено для этого. Объявление свойства таким способом не предотвращает случайное изменение массива кем-либо.

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

- (NSArray *)myArray { return [NSArray arrayWithArray:myArray]; }

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

Вы видите ошибки, потому что XCode теперь выдает предупреждения и ошибки для вещей, которых раньше не было ...

Я бы сказал, что делать то, что вы делаете, должно быть самое большее предупреждение. Я понимаю вашу попытку представить массив как неизменяемый для внешнего мира, но сделать его изменяемым внутри класса. Возможно, вы захотите рассмотреть другой метод доступа с другим именем, специально созданный для возврата изменяемого массива.

Это все еще Objective-C 2.0; Компилятор, возможно, немного обновлен, учитывая, что этот тип типа изменяет ошибку. Это в значительной степени должно быть ошибкой. По крайней мере, это должно предупредить вас, что вы, скорее всего, не имеете в виду то, что написали. Затем вы могли бы привести данные, чтобы они вас не предупреждали, чего нельзя сделать с помощью оператора @synthesize .

Я просто вставил твой код и оператор синтеза в свой контроллер и не получил никаких ошибок или предупреждений об этом. Он построен хорошо. Теперь я установил для базового SDK «Simulator 3.0», а для сборки «Simulator 3.0 Debug». Этот проект начался в 2.2.1 SDK, и я только вчера установил 3.0 SDK; Xcode - версия 3.1.3.

Обновление . О, я вижу, что на самом деле попытка установить свойство - это то место, где вы получили указанную ошибку.

    self.myArray = [NSArray arrayWithObject:@"foo"];

Ясно, что вы не можете @synthesize этого поведения и должны написать свои собственные методы доступа.

- (NSArray*)myArray {
    return [NSArray arrayWithArray:myArray];
}
- (void)setMyArray:(NSArray*) pMyArray {
    myArray = [NSMutableArray arrayWithArray:pMyArray];
}

Заполнение этих методов доступа не привело к исчезновению сообщения, поэтому мне пришлось изменить доступ на:

    [self setMyArray:[NSArray arrayWithObject:@"foo"]];

Использование приведенного выше синтаксиса без пользовательских средств доступа также не помогло.

PS Ого, кого-то еще раздражает, что вы не можете ни копировать пузырьки сообщений, ни текст в окне результатов сборки?

Так что это действительно связано с вызовом @synthesize, который не рад представить NSMutableArray как NSArray - почему бы просто не реализовать getMethod.

На самом деле, думая об этом, это должен быть метод set, который не устраивает - вы не сможете установить NSArray в NSMutableArray.

Ваши вопросы были:

  

Кто-нибудь знает об изменениях в target-c между ОС 2.2.1 и 3.0?

     

Есть ли документация для этих изменений?

Окончательные ответы:

1) В спецификации языка не было преднамеренных изменений, но изменился компилятор и другие инструменты разработчика. Крис и его коллеги являются экспертами в этих изменениях.

2) Вероятно, нет, потому что любые изменения были непреднамеренными или сделаны для лучшего соответствия поведения с документацией.

Не стоит так быстро отклонять ответ Криса как "предположение". Крис работает над инструментами разработчика Apple. Вы можете получить другой ответ, который вам больше нравится, но вы не получите более квалифицированный ответ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top