【问题标题】:NSBundle can't unload dynamic frameworkNSBundle 无法卸载动态框架
【发布时间】:2016-12-29 21:43:57
【问题描述】:

对不起,我的英语不好,但我会清楚地描述我的问题。

我正在尝试实现下载动态框架并将其加载到我们的“InHouse”应用程序中。(请参阅article)(因为 InHouse 应用程序,我们不关心 AppStore。)

下载、加载和使用动态框架就可以了!它工作正常。

但是当我尝试卸载它并下载新的动态框架(相同的框架名称但在类中不同。)来加载它。(所有旧框架将在加载新框架之前卸载并删除。)但该类仍然是旧类.

卸载框架代码:

NSBundle *bundle = [NSBundle bundleWithPath:documentsPath];
result = [bundle unload]; // I use break point, it says unload MyFramework.framework.

[self removeBundleAndZip]; // It's just a function to remove bundle files.

但它仍然可以使用该类。我很确定这个类是 dealloc (我在类 dealloc 时打印它。)。我猜想缓存这个类是 Objective-C 运行时。

于是我又找了一篇文章(How to remove NSBundle cache),就这样添加了:

NSBundle *bundle = [NSBundle bundleWithPath:documentsPath];
result = [bundle unload]; // I use break point, it says unload MyFramework.framework.

if ( FlushBundleCache(bundle) ) {
    NSLog(@" ** Success: flush bundle cache SUCCESS ...");
}
else{
    NSLog(@" ** Faile: flush bundle cache FAIL! ");
}

[self removeBundleAndZip]; // It's just a function to remove bundle files.

刷新成功,但卸载旧框架后仍然无法加载和使用新框架。 (加载是好的,但框架中的旧类不是新类,如果我重新启动应用程序,它将使用新框架。这表明如果我们重新启动应用程序就可以下载并加载。)

有没有办法卸载旧框架并加载新框架但不重新启动应用程序?

PS:这是我的加载框架代码...

NSString *documentsPath = [NSString stringWithFormat:@"%@/Documents/%@/%@",NSHomeDirectory() , @"frameworkFolder" , @"myDownloadFramework.framework"];

if ( [[NSFileManager defaultManager] fileExistsAtPath:documentsPath] ) {

    NSError *error = nil;
    NSBundle *bundle = [NSBundle bundleWithPath:documentsPath];

    if ( [bundle loadAndReturnError:&error] ) {
        if ( error ) {
            NSLog(@"Fail: NSBundle load framework fail.( %@ )" , error.description);
        }
        else{
            NSLog(@"Success: NSBundle load framework success!");
            result = YES;
        }
    }
    else{
        NSLog(@"Fail: NSBundle load framework fail.");
    }
}
else{
    NSLog(@"Fail: NSBundle load framework fail.( file not exist )");
}

使用我在下载框架中的类

Class myClass = objc_getClass("MyClassInFramework");

使用类方法

SEL myMethod = @selector(myMethodInClass);
if( [myClass responseToSelector:myMethod] ){
    objc_msgSend( myClass , myMethod , nil );
}

PS:我们需要这样做,因为如果我们有新的更新,我们希望阻止始终发布我们的应用程序。

【问题讨论】:

  • 我认为苹果会阻止这种方式在 iOS 10 之后加载动态框架。悲伤:(
  • 是的,我也试过了,还是不行

标签: ios dynamic frameworks load nsbundle


【解决方案1】:

也许你不应该在你的框架中使用 ARC。

我认为应用程序仍然会加载框架,直到您将其杀死。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多