首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Cordova-Angularjs应用程序在多次文件请求后在iPad上停止

Cordova-Angularjs应用程序在多次文件请求后在iPad上停止
EN

Stack Overflow用户
提问于 2014-12-15 19:27:09
回答 1查看 232关注 0票数 1

我正在尝试用Cordova和AngularJs编写一个iPad应用,它会在启动时自动更新。因此我复制了很多文件(js,css,图像,...)当应用程序过期时。

在iPad-App冻结了大约400个文件之后,将不再处理延迟事件。我已经剥离了我的应用程序,并来到这个测试应用程序,它基本上是连续10000次初始化文件系统:

代码语言:javascript
复制
<!-- language: lang-js -->
angular.module('tablet', []).controller('StartCtrl', ['$scope', '$http', '$q',
    function($scope, $http, $q) {
        document.addEventListener("deviceready", onDeviceReady, false);

        function onDeviceReady() {
            console.log('deviceready');
            testFileSystem($q);
        }
    }
]);

function testFileSystem($q) {
    var defer = $q.defer();
    var chain = defer.promise;
    defer.resolve();
    // chaining 10000 init filesystem requests    
    for (var i = 0; i < 10000; i++) {
        chain = chain.then(startInitFileSystem($q, i));
    }
}

function startInitFileSystem($q, i) {
    return function() {
        return initFileSystem($q, i);
    }
}

function initFileSystem($q, i) {
    console.log('Init FileSystem: ' + i);
    var defer = $q.defer();
    window.requestFileSystem(PERSISTENT, 1024 * 1024 * 1024, function(fs) {
        fileSystem = fs;
        defer.resolve();
    }, function() {
        console.log("Init FileSystem failed");
        defer.reject();
    });
    return defer.promise;
}

在997请求应用程序停止后,不再触发任何延迟事件。在调试angularjs defer对象时,我可以将问题范围缩小到方法:

代码语言:javascript
复制
<!-- language: lang-js -->
self.defer = function(fn, delay) {
    var timeoutId;
    outstandingRequestCount++;
    try {
        timeoutId = setTimeout(function() {
            delete pendingDeferIds[timeoutId];
            completeOutstandingRequest(fn);
        }, delay || 0);
    } catch (e) {
        console.log(e.message);
    }
    pendingDeferIds[timeoutId] = true;
    return timeoutId;
};

会调用setTimeout,但不会在出错时触发。

这会不会是某种内存泄漏?令人惊讶的是,如果你不使用角度延迟,它就能正常工作。在延迟解决后,有没有办法清理它?

我使用的是cordova插件:设备、记录器和文件。

EN

回答 1

Stack Overflow用户

发布于 2015-01-08 20:27:08

我也有同样的问题。问题是您的内存正在运行,这是由iOS设备上的setTimeout发生泄漏的完全原因。

您可以通过使用工具和运行分配工具来验证这一点。在真实设备上运行您的示例并连接到该进程。在连接时运行您的示例。您应该会看到一个不断增长的分配图。当您在不使用任何setTimeout调用的情况下重新实现示例时,垃圾收集器将按其应有的方式清除所有内容。请注意,垃圾收集有点懒惰,只有在分配了一定数量的内存后才会启动。所以你需要重新运行你的代码。

我的示例代码是在创建测试cordova项目时添加到app对象的:

代码语言:javascript
复制
run: function () {
    function error(err) {
        alert(err);
    }

    window.requestFileSystem(window.PERSISTENT, 0, function (fs) {
        function tick(i) {
            return function () {
                if (i > 1000) return;
                fs.root.getDirectory(String(i), { create: true }, function () {
                    setTimeout(next(i + 1), 0); // Removing setTimeout solves the memory leak
                }, error);
            };
        }
        tick(0)();
    }, error);
}

注意,即使函数已经完成处理,内存分配也会保持不变,如果没有setTimeout,内存将在进程完成后被垃圾回收。我目前不知道为什么会发生这种情况,但如果它真的与setTimeout调用有关,应用程序中的每个调用都可能导致泄漏。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27483000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档