NSBundle无法卸载动态框架

时间:2016-08-23 07:22:40

标签: ios dynamic frameworks load nsbundle

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

我正在尝试实施下载动态框架并将其加载到我们的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.

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

有没有办法卸载旧框架并加载新框架但不重启App?

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:我们需要这样做,因为如果我们有新的更新,我们希望阻止发布我们的应用程序。

1 个答案:

答案 0 :(得分:0)

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

我认为该应用程序仍会加载框架,直到您将其删除。