Objective-C меняется между OS 2.2.1 и OS 3? - PullRequest
7 голосов
/ 19 июня 2009

Когда я попытался скомпилировать свое приложение для 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.

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

Ответы [ 6 ]

17 голосов
/ 23 июня 2009

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

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

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

@implementation Foo
@synthesize objects;
@end

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

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

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

@implementation Foo
@synthesize objects = _objects;
@end

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

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

5 голосов
/ 19 июня 2009

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


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

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

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

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

4 голосов
/ 19 июня 2009

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

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

1 голос
/ 20 июня 2009

Это все еще 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 Ого, кого-то еще раздражает, что вы не можете ни копировать пузырьки сообщений, ни текст в окне результатов сборки?

0 голосов
/ 28 июня 2009

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

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

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

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

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

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

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

0 голосов
/ 19 июня 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...