2017-02-19 5 views
1

私は、スウィズルなどの埋め込みフレームワークを+loadメソッドで使用しています。コードでiOSに組み込みフレームワークを明示的にロードすると、allocとclassはnilオブジェクトを返します

フレームワークが実際にロードされた状況(私はいつもそれを使用するとは限りません)に関しては、より細かい制御が必要です。

手動でロードするには、「埋め込みバイナリ」セクションからフレームワークを削除してください。

フレームワークは、今ではなく、「必須」より「オプション」としてリンクされている

- 明示的に、アプリケーションのリソースへの(ないframeworksディレクトリにフレームワークをコピーする(これは試行錯誤で違いは何ですか?)

「埋め込みバイナリ」セクション参照)。私のコードで

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クラス名は、コンパイルされたモジュールによって修飾されます。 dlopenされたフレームワークの名前をスワイプクラス名の前に付けます。拡張子のないフレームワーク名だけです。アプリバンドル名ではありません。

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

関連する問題