Подтвердить что ты не робот

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

Теперь, когда Xcode4 является общедоступным, я перехожу из этого вопроса из секретного форума Apple:

Может кто-нибудь объяснить, почему код, сгенерированный в следующей процедуре, отличается от кода Xcode3? Является ли код лучше или это может быть ошибкой?

Я использую настраиваемые управляемые классы Core Data, и это была процедура, которую я выполнил в Xcode3:

  • Перейти к редактору моделей
  • Выберите объект, который вы хотите создать исходный код для
  • Перейдите в меню Файл- > Создать- > Новые файлы
  • Выберите класс managedobject (или что бы это ни было, я больше не могу открыть xcode3 для проверки)
  • Выберите объекты, которые вы хотите сгенерировать (ранее выбранный объект на шаге 2 был отключен)
  • Нажмите "Готово"

Теперь, в Xcode4, я ДУМАЮ, вот как это сделать, но я не уверен, потому что он генерирует другой код:

  • Перейти к редактору моделей
  • Выбрать объект
  • Перейдите в меню Файл- > Новый- > Новый файл
  • Выберите "Подкласс NSManagedObject"
  • Выберите местоположение и создайте.

Код, который он генерирует, отличается по ряду причин:

  • Сгенерированный код для добавления и удаления членов набора в сущности больше не объявляется в @interface, а вместо @implementation. Это приводит к тому, что код не может обнаружить эти методы.
  • Тот же сгенерированный код для добавления и удаления объектов теперь полностью определен, больше не автогенерируется с использованием CoreDataGeneratedAccessors

Например, Xcode3 сгенерировал бы этот код в файле HEADER:

@interface SampleEntity (CoreDataGeneratedAccessors)
- (void)addChildObject:(Child *)value;
- (void)removeChildObject:(Child *)value;
- (void)addChild:(NSSet *)value;
- (void)removeChild:(NSSet *)value;
@end

Теперь Xcode4 генерирует этот код в файле IMPLEMENTATION:

@implementation SampleEntity
@dynamic children;
- (void)addChildObject:(Child *)value {    
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
    [self willChangeValueForKey:@"children" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    [[self primitiveValueForKey:@"children"] addObject:value];
    [self didChangeValueForKey:@"children" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    [changedObjects release];
}

Может кто-то верить, почему это другое? Кодировка кода Xcode4 не нравится новому способу создания подклассов NSManagedObject.

4b9b3361

Ответ 1

Короткий ответ: Не используйте генерацию кода Xcode. Используйте mogenerator и наслаждайтесь более легкой жизнью.

Что касается того, почему, трудно сказать. Я никогда не был поклонником того, как Xcode генерирует подклассы Core Data и не рекомендует их. Мы могли догадаться, почему они сделали то, что они сделали, но на основании других проблем с Xcode4 и Core Data я сделал бы это для "не готового" или "не полностью протестированного".

Файл радара, если вы хотите продолжать использовать генератор кода Xcode.

Ответ 2

Похоже, все, что сделал Xcode4, - это сделать явным, что директива @dynanmic делает неявной. Сгенерированный код выглядит точно так же, как и сгенерированный Xcode3, когда вы попросили его создать аксессоры для определенного атрибута (в буфер обмена).

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

Не должно быть так сложно, чтобы кто-то помог MOGenerator в Xcode4. Подсказка Подсказка. Кто угодно? Давайте, ребята! Кто угодно? Bueller?

Вздох, похоже, это я.

Ответ 3

Моногенератор не подключается к Xcode 4, поэтому вы можете использовать командную строку для запуска сгенерированных сценариев:

mogenerator -m Resources/CoreData/XcodeProj.xcdatamodeld/XcodeProj1.xcdatamodel --base-class RootManagedObjectClass --template-path Resources/MoGenerator -O Sources/Classes

Ответ 4

Я обнаружил ту же проблему месяц назад, и опубликовал ее на форумах предварительного просмотра Xcode 4 в Apple. Ответа не было. Чтобы получить работу с моим, я просто схватил сигнатуры метода из файла .m и создал категорию в файле .h. В основном взломанный сгенерированный код вернулся к тому, как XCode 3 сделал бы это. Я не пробовал с новой версией Xcode 4.

Ответ 5

Я использую старый способ XCode 3, описанный в XCode 4 (последний с iOS4.3), и он работает по-прежнему, и то, что он создает для меня, это:

    
#import <CoreData/CoreData.h>
@class JiraIssueType;
@class JiraPriority;
@class Customer;
@class JiraComment;
@class JiraComponent;
@class JiraUser;
@class Report;
@class Tag;

@interface JiraIssue :  NSManagedObject  
{
}

@property (nonatomic, retain) NSString * jiraId;
@property (nonatomic, retain) NSString * summary;
@property (nonatomic, retain) NSString * detailedDescription;
@property (nonatomic, retain) NSDate * createdDate;
@property (nonatomic, retain) NSDate * lastUpdatedDate;
@property (nonatomic, retain) NSString * key;
@property (nonatomic, retain) Report * report;
@property (nonatomic, retain) NSSet* comments;
@property (nonatomic, retain) JiraPriority * priority;
@property (nonatomic, retain) NSSet* components;
@property (nonatomic, retain) JiraIssueType * type;
@property (nonatomic, retain) Customer * customer;
@property (nonatomic, retain) NSSet* tags;
@property (nonatomic, retain) JiraUser * assignedTo;

@end


@interface JiraIssue (CoreDataGeneratedAccessors)
- (void)addCommentsObject:(JiraComment *)value;
- (void)removeCommentsObject:(JiraComment *)value;
- (void)addComments:(NSSet *)value;
- (void)removeComments:(NSSet *)value;

- (void)addComponentsObject:(JiraComponent *)value;
- (void)removeComponentsObject:(JiraComponent *)value;
- (void)addComponents:(NSSet *)value;
- (void)removeComponents:(NSSet *)value;

- (void)addTagsObject:(Tag *)value;
- (void)removeTagsObject:(Tag *)value;
- (void)addTags:(NSSet *)value;
- (void)removeTags:(NSSet *)value;

@end

Ответ 6

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

Я использую эти фрагменты в качестве альтернативы:

- (void)add<#entity#>sObject:(<#entity#> *)value;
- (void)remove<#entity#>sObject:(<#entity#> *)value;
- (void)add<#entity#>s:(NSSet *)value;
- (void)remove<#entity#>s:(NSSet *)value;