2017-02-19 34 views
1

Я использую встроенную фреймворк, который делает swizzling и другие вещи в своих методах +load.При явной загрузке встроенной фреймворка в iOS через код, alloc и class возвращает объект nil

Мне нужен более тонкий контроль, как в тех ситуациях, когда структура загружается (я не всегда ее использую).

Чтобы загрузить его вручную - то, что я пытался сделать, это удалить структуру из раздела «встроенные двоичные файлы».

Каркас теперь связан как «дополнительный», а не «требуется» (это метод проб и ошибок - в чем разница)

Явное копирование базы к ресурсам приложения (не в директорию рамок, как раздел «встроенные двоичные файлы»).

enter image description here

enter image description here

В моем коде я только загрузки рамки, когда я на самом деле нужно использовать его, выполнив следующие действия (это правильно загрузить, используя dlopen таким образом?):

#import <MyFramework/MyFramework.h> 
- (void)someplaceWhichNeedsToUseTheFramework 
{ 
    dispatch_once(&onceToken, ^{ 
    [self loadFrameworkDynamic:@"TheFramework"]; 
    }); 
    // do something with framework 


    //>>>>>>>>>>>> This is the problem 
    // Does not work! 
    SomeClassFromFramework *obj = [SomeClassFromFramework alloc] init]; 
    // <<<<<<<<<<<<<<<< 
    // Instead I must use the runtime syntax which does work. Why is this? 


Class theClass = NSClassFromString(@"SomeClassFromFramework"); 
    [[theClass alloc] init]; 

// I've tried using the ordinary syntax again after this point but still not working 
    SomeClassFromFramework *obj2 = [SomeClassFromFramework alloc] init]; // <<<<<<< still nil! 
} 

- (void)loadFrameworkDynamic:(NSString *)libName 
{ 
    //WidgetSource is the name of framework 

    NSString *libExtension = @"framework"; 
    NSString *path = [[NSBundle mainBundle] pathForResource:libName ofType:libExtension]; 
    NSLog(@"Loading dynamic library: %@", path); 
    path=[path stringByAppendingString:[NSString stringWithFormat:@"/%@",libName]]; 

    void *revealLib = NULL; 
    revealLib = dlopen([path cStringUsingEncoding:NSUTF8StringEncoding], RTLD_NOW); 

    if (revealLib == NULL) 
    { 
    char *error = dlerror(); 
    NSLog(@"dlopen error: %s", error); 
    } 
} 

ответ

1

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

0

Название класса Swift квалифицируется модулем, в котором он скомпилирован. Префикс вашего быстрого имени класса с названием рамки, которую вы создали. Просто имя структуры без расширения, а не имя приложения.

Class theClass = NClassFromString(@"TheFramework.SomeClassFromFramework");

Смежные вопросы