Расширения класса Objective-c не эффективны в статической библиотеке - PullRequest
3 голосов
/ 01 октября 2010

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

Библиотека состоит из нескольких «модулей», каждый из которых объявляет свой наборклассы.Модули объявляют заголовочный файл, который ссылается на классы.Каждый заголовок модуля включается в заголовок библиотеки, и все они копируются в целевую библиотеку.

Модуль «GMData» определяет уровень ORM библиотеки, объявляет класс «GMInitializerBase» и его назначение.это инициализировать модуль.Он должен вызываться один раз в UIApplicationDelegate.

Модуль «GMModel» содержит базовую модель для приложения (Категории, Статьи, ...). Он должен зарегистрироваться в «GMData» для правильной работы..

Структура:

<Library Root>
    Library.h
    <GMData>
        GMData.h
        GMInitializerBase.{h,m}
    <GMModel>
        GMModel.h
        GMInitializerBase+GMModel.{h,m}

Содержимое Library.h

#import "GMData.h"
#import "GMModel.h"

Содержимое GMData.h

#import "... ORM related headers ..."
#import "GMInitializerBase.h"

Содержимое GMInitializerBase.{h, m}

#import "... ORM Classes ..."

@interface GMInitializerBase : NSObject {

}

+ (void) bootstrap;
+ (GMInitializerBase*) initializer; // autoreleased instance creator

- (void) setup;
- (void) setupStore:(GMManagerFactory*)factory; // Setup database connection
- (void) setupHelpers:(GMHelperFactory*)factory; // Register helpers (abstract)
- (void) setupManagers:(GMManagerFactory*)factory; // Register managers (abstract)

@end

@implementation GMInitializerBase

+ (void) bootstrap {
    GMInitializerBase* initializer = [self initializer];

    [initializer setup];
}

- (void) setup {
    /* Breakpoint 01 */
    GMHelperFactory* helperFactory = [GMHelperFactory sharedInstance];
    GMManagerFactory* managerFactory = [GMManagerFactory sharedInstance];

    [self setupStore:managerFactory];
    [self setupHelpers:helperFactory];
    [self setupManagers:managerFactory];
}

@end

Содержимое GMModel.h

#import "... Base Models files ..."
#import "GMInitializerBase+GMModel.h"

Содержимое GMInitializerBase + GMModel. {h, m}

@interface GMInitializerBase (GMModel_Additions)

- (void) setup;
- (void) setupGMModelHelpers:(GMHelperFactory*)factory;
- (void) setupGMModelManagers:(GMManagerFactory*)factory;

@end

@implementation GMInitializerBase (GMModel_Additions)

- (void) setup {
    /* Breakpoint 02 */
    GMHelperFactory* helperFactory = [GMHelperFactory sharedInstance];
    GMManagerFactory* managerFactory = [GMManagerFactory sharedInstance];

    // parent implementation
    [self setupStore:managerFactory];

    // current implementation
    [self setupGMModelHelpers:helperFactory];
    [self setupGMModelManagers:managerFactory];

    // parent implementation
    [self setupHelpers:helperFactory];
    [self setupManagers:managerFactory];
}

- (void) setupGMModelHelpers:(GMHelperFactory*)factory { /* ... */ }
- (void) setupGMModelManagers:(GMManagerFactory*)factory { /* ... */ }

@end

СодержимоеProjectAppDelegate.m (находится в другом проекте, включает в себя library.a и выполняет поиск в каталоге «Заголовки»)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[GMInitializerBase initializer] setup];
}

Останавливается на первой точке останова (точка останова 01) Сбой при работе в библиотеке:

  • Я объявляю добавление без перегрузки метода;
  • Я объявляю добавление к классу Какао ([NSString toto]) без перегрузки;

В работахкогда в тестовом проекте:

  • я объявляю дополнение к классу какаоs ([NSString toto]) без перегрузки;

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

Моя проблема заключается в следующем: Iне могу получить рабочее дополнение, и мне оно нужно.

Спасибо за чтение, спасибо за ответ.

Ответы [ 2 ]

9 голосов
/ 01 октября 2010

Убедитесь, что в настройках проекта установлены флаги -all_load и -ObjC в разделе «Другие флаги компоновщика».Категории в библиотеке не будут работать без них.

0 голосов
/ 02 октября 2010

В Objective-C не следует переопределять метод в категории класса.Скажем, у вас есть

@implementation MyClass
-(void)foo
{
    NSLog(@"%@",@"original!");
}
@end

и позже у вас есть

@implementation MyClass (MyCategoryA)
-(void)foo
{
    NSLog(@"%@",@"categoryA!");
}
@end

@implementation MyClass (MyCategoryB)
-(void)foo
{
    NSLog(@"%@",@"categoryB!");
}
@end

Тогда результат

MyClass* myInstance=...;
[myInstance foo];

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

Единственное исключение - +load.Если категория определяет этот метод, среда выполнения вызывает его для каждой определенной вами категории.Итак, если вы хотите выполнить какую-то задачу инициализации для каждой категории, лучше всего использовать +load.Прочитайте официальную документацию и это сообщение в блоге Майка Эша.

...