Странная ошибка присваивания
Почему это работает:
- (void) setupInteraction:(IBITSInteraction*)interaction withInfo:(NSDictionary*)info
{
CGRect rect = ([info objectForKey:kInteractionFrameKey] ? CGRectFromString([info objectForKey:kInteractionFrameKey]) : CGRectZero);
interaction.frame = rect;
...
}
а почему этого нет?
- (void) setupInteraction:(IBITSInteraction*)interaction withInfo:(NSDictionary*)info
{
interaction.frame = ([info objectForKey:kInteractionFrameKey] ? CGRectFromString([info objectForKey:kInteractionFrameKey]) : CGRectZero);
...
}
Я думаю, что точно так же...
- Компилятор: LLVM GCC 4.2
- Ошибка (второй случай): присвоение переменной только для чтения "prop.283"
- Фрейм недвижимости:
@property (nonatomic, assign) CGRect frame;
с соответствующими@synthesize
Заранее спасибо.
2 ответа
Это ошибка в интерфейсе GCC 4.2, также воспроизводимая в LLVM-GCC 4.2. Поздравляем! Эти компиляторы сталкиваются с проблемами при назначении свойств с использованием точечного синтаксиса, когда присваиваемое значение является выражением, полученным в результате условного оператора.
Следующий код воспроизводит проблему и показывает два решения исходного кода: один, как вы заметили, использует временную переменную. Другое решение заключается в использовании традиционного синтаксиса отправки сообщений Objective-C вместо точечного синтаксиса:
#import <Foundation/Foundation.h>
CGRect CGRectFromString(NSString *string);
@interface SomeClass : NSObject
@property (nonatomic, assign) CGRect frame;
@end
@implementation SomeClass
@synthesize frame;
@end
int main(void) {
NSDictionary *info;
SomeClass *interaction;
NSString *kInteractionFrameKey;
CGRect rect;
rect = [info objectForKey:kInteractionFrameKey] ? CGRectFromString([info objectForKey:kInteractionFrameKey]) : CGRectZero;
interaction.frame = rect;
[interaction setFrame:([info objectForKey:kInteractionFrameKey] ? CGRectFromString([info objectForKey:kInteractionFrameKey]) : CGRectZero)];
interaction.frame = ([info objectForKey:kInteractionFrameKey] ? CGRectFromString([info objectForKey:kInteractionFrameKey]) : CGRectZero);
interaction.frame = ([info objectForKey:kInteractionFrameKey] ? CGRectZero : CGRectFromString([info objectForKey:kInteractionFrameKey]));
interaction.frame = ([info objectForKey:kInteractionFrameKey] ? CGRectZero : CGRectZero);
return 0;
}
Тестирование с разными компиляторами дает следующее:
$ llvm-gcc -c test.m
test.m: In function ‘main’:
test.m:24: error: assignment of read-only variable ‘prop.76’
test.m:25: error: assignment of read-only variable ‘prop.77’
test.m:26: error: assignment of read-only variable ‘prop.78’
$ clang -c test.m
$
Вы можете использовать LLVM или избежать точечного синтаксиса в этом конкретном случае. Возможно, вы захотите сообщить об ошибке, но я бы не стал задерживать дыхание, поскольку Apple вряд ли обновит GCC.
Я пробовал этот код в общем методе уведомлений в GCC 4.2, LLVM GCC 4.2 и Apple LLVM 2.1. Никто из них не дал мне ошибок. Итак, что-то происходит с вашей установкой Xcode и / или установкой компилятора.