Нераспознанный селектор Objective-C при +инициализации с помощью MagicalRecord CocoaPod

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

Я считаю, что это проблема с настройкой моего проекта, но я не уверен, на что смотреть, потому что ошибок компиляции нет.

У меня есть MagicalRecord 2.1 (текущая стабильная версия), включенная в проект, и CocoaPods управляет им. Я не менял никаких настроек сборки для CocoaPods, он отлично управляет другими моими зависимостями, и до сих пор у меня не было никаких проблем с ним.

Я добавил #import <MagicalRecord/CoreData+MagicalRecord.h> в свой файл App-Prefix.pch, и Xcode предоставляет мне все предложения символов, которые я мог бы ожидать при правильной настройке. Я не получаю никаких ошибок компилятора, поэтому я могу только предположить, что CocoaPods успешно встроила MR в библиотеку, и я успешно импортирую ее в свой код.

Проблема возникает, когда я инициализирую MagicalRecord в своем делегате приложения:

- (void)applicationDidFinishLaunching:(NSNotification *)notification {
  [MagicalRecord setupCoreDataStack];

  //... other code
}

Инициализация — это почти первый код, который нужно запустить, и нет ничего другого, что могло бы конфликтовать с этим.

Эта строка висит, после этой строки ничего не выполняется. Мне удалось отследить, где происходит зависание. Передача сообщения в MagicalRecord приводит к тому, что класс вызывает +initialize, а это не работает. В частности, любой метод self, который вызывается в методе инициализации, вызывает исключение unrecognized selector.

Насколько я вижу, в этом есть две странные вещи:

  1. Почему он не может найти реализации метода?
  2. Почему это приводит к зависанию?

Я недостаточно знаю о том, как Objective-C использует метод инициализации, ожидается ли зависание, когда в нем возникают исключения?

Вот трассировка стека при возникновении исключения:

frame #0: 0x00007fff93a2e3c5 libobjc.A.dylib`objc_exception_throw
frame #1: 0x00007fff996dc31a CoreFoundation`+[NSObject(NSObject) doesNotRecognizeSelector:] + 186
frame #2: 0x00007fff996341ee CoreFoundation`___forwarding___ + 414
frame #3: 0x00007fff99633fd8 CoreFoundation`_CF_forwarding_prep_0 + 232
frame #4: 0x000000010004e32c River`+[MagicalRecord initialize] + 92 at MagicalRecord.m:89
frame #5: 0x00007fff93a25236 libobjc.A.dylib`_class_initialize + 310
frame #6: 0x00007fff93a250f3 libobjc.A.dylib`prepareForMethodLookup + 164
frame #7: 0x00007fff93a24eef libobjc.A.dylib`lookUpMethod + 71
frame #8: 0x00007fff93a232fc libobjc.A.dylib`objc_msgSend + 188
frame #9: 0x0000000100001d36 MyApp`-[AppDelegate applicationDidFinishLaunching:] + 86 at AppDelegate.m:46

Любая помощь в этом, включая приемы, которые я могу попытаться отладить, очень ценится.

Обновление:

После удаления каталога Derived Data программе не удалось установить связь с модулями. Я считаю, что Xcode не смог собрать модули после того, как я добавил MagicalRecord и связал его с более старой версией (может быть, это неправильно, я не уверен).

Похоже, это проблема Xcode и/или CocoaPods. Я пытаюсь выяснить, как мне заставить его правильно построить Pod, но я не эксперт по настройкам сборки CocoaPods или Xcode, поэтому я не уверен, как далеко я продвинусь.

Обновление 2:

Была возникла проблема с Xcode и настройкой проекта, связанная со старой библиотекой Pod, которая вызывала проблемы только после удаления производных данных. Теперь я вернулся к квадрату 1 с проблемой непризнанного селектора.


person danpalmer    schedule 31.01.2013    source источник
comment
Похоже, проблема с чем-то, что вы вызываете, или с самим MagicalRecord.   -  person Keith Smiley    schedule 31.01.2013
comment
Это то, что я мог бы подумать, но, поскольку никто другой не сообщил о проблеме, я подозреваю, что это проблема с настройкой моего проекта. Но я недостаточно знаю о внутренностях Objective-C, чтобы понять, почему он не сможет найти методы.   -  person danpalmer    schedule 31.01.2013


Ответы (4)


Решение заключается в использовании флага компоновщика -all_load в параметрах Другие флаги компоновщика в настройках продукта, использующего библиотеку Pod.

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

person sbwilson    schedule 24.02.2013
comment
Это достаточно близко, поэтому отмечено как ответ. Настоящая проблема заключалась в том, что -all_load и -ObjC не использовались в самом основном проекте, а не в проекте Pods. - person danpalmer; 24.02.2013
comment
Добавление флага -all_load вызывает ошибку duplicate symbol _OBJC_CLASS_$_AFImageCache. - person derpoliuk; 28.11.2013

Извините, я так и не решил эту проблему, и похоже, что никто не знает, почему она не работает. Я пытался решить это с разработчиком Magical Record, но в итоге получил ответ: не использовать CocoaPods и добавить код вручную. Я хотел бы дать лучшее решение этой проблемы, но у меня нет времени тратить дни на отладку этой проблемы, и я не думаю, что знаю достаточно о CocoaPods, процессе компиляции Xcode и среде выполнения Objective-C, чтобы для его отладки.

person danpalmer    schedule 15.02.2013

Я вручную добавил библиотеку MagicalRecord и столкнулся с этой ошибкой. Моя проблема была в файле .pch, потому что импорт MagicalRecord/CoreData+MagicalRecord.h был выше определения: #define MR_SHORTHAND.

Установка импорта определения выше решила проблему для меня.

person Legoless    schedule 21.07.2013

В вашем Podfile обновлении ссылка на MagicalRecord выглядит следующим образом:

pod 'MagicalRecord/Shorthand', '~> 2.2'

Он будет включать #define MR_SHORTHAND в ваш файл Pods/Pods-MagicalRecord-prefix.pch.

person boro    schedule 25.06.2014