AS3 встраивают или импортируют все классы во внешнем swf, не ссылаясь на каждый класс отдельно

Рассмотрим следующий объект keyValueStore:

var keyValueStore = (function() {
    var count = 0;
    var kvs = function() {
        count++;
        this.data = {};
        this.get = function(key) { return this.data[key]; };
        this.set = function(key, value) { this.data[key] = value; };
        this.delete = function(key) { delete this.data[key]; };
        this.getLength = function() {
            var l = 0;
            for (p in this.data) l++;
            return l;
        }
    };

    return  { // Singleton public properties
        'create' : function() { return new kvs(); },
        'count' : function() { return count; }
    };
})();

Я могу создать новый экземпляр этого объекта, выполнив следующее:

kvs = keyValueStore.create();

Каждый экземпляр этого объекта будет иметь Следующие общедоступные свойства:

  • data
  • get
  • set
  • delete
  • getLength

Теперь предположим, что мы создали 100 экземпляров этого keyValueStore объекта. Даже если get, set, delete, getLength будут делать одно и то же для каждого из этих 100 экземпляров, каждый экземпляр имеет свою копию этой функции.

Теперь представьте, что у вас может быть только одна копия get, set, delete и getLength, и каждый экземпляр будет ссылаться на ту же функцию. Это было бы лучше для производительности и потребовало бы меньше памяти.

Вот где появляются прототипы. Прототип - это «план» свойств, который наследуется, но не копируется экземплярами. Таким образом, это означает, что он существует только один раз в памяти для всех экземпляров объекта и является общим для всех этих экземпляров.

Теперь рассмотрим объект keyValueStore снова. Я мог бы переписать это так:

var keyValueStore = (function() {
    var count = 0;
    var kvs = function() {
        count++;
        this.data = {};
    };

    kvs.prototype = {
        'get' : function(key) { return this.data[key]; },
        'set' : function(key, value) { this.data[key] = value; },
        'delete' : function(key) { delete this.data[key]; },
        'getLength' : function() {
            var l = 0;
            for (p in this.data) l++;
            return l;
        }
    };

    return  {
        'create' : function() { return new kvs(); },
        'count' : function() { return count; }
    };
})();

Это ТОЧНО точно так же, как и в предыдущей версии объекта keyValueStore, за исключением того, что все его методы теперь помещены в прототип. Это означает, что все 100 экземпляров теперь совместно используют эти четыре метода вместо того, чтобы каждый имел свою собственную копию.

6
задан Michael Petrotta 11 September 2011 в 03:51
поделиться

4 ответа

Вместо использования SWF лучше использовать SWC. Чтобы создать SWC, просто зайдите в настройки публикации Flash Pro, перейдите на вкладку Flash и выберите «Экспорт SWC». SWC содержит как SWF, так и специальный манифест со всей информацией, которую Flash должна знать о классах в SWF.

Затем, чтобы использовать SWC в другом проекте, вы переходите к настройкам AS3 (также во вкладке Flash параметров публикации), перейдите на вкладку «Путь к библиотеке» и добавьте свой SWC (как абсолютные, так и относительные пути работают нормально).

Обратите внимание, что это будет работать только в CS4 или Flex (я уверен, что с Flex вы можете просто перетащить SWC в ваш проект, но я проверю это).

Теперь - если вы хотите загрузить SWF и использовать его ресурсы во время выполнения, это совсем другое дело. Чтобы это работало правильно, вы » Мне нужно повозиться с классом Loader и ApplicationDomain, чтобы классы были помещены в соответствующий домен. Вот полезная информация по этому вопросу:

http://www.kirupa.com/forum/showpost.php?p=2123134&postcount=366

4
ответ дан 8 December 2019 в 18:40
поделиться

Итак, это случай, когда CS4 слишком умен для собственного блага. Поскольку вы никогда не явно ссылаетесь на рассматриваемые классы способом, который компилятор может определить во время компиляции, он не включает эти классы в ваш SWF - отсюда и ошибка.

В Flex вы можете обойти это с помощью аргумента командной строки, но это не относится к CS4. Вместо этого у вас есть явная ссылка на классы, которые вы хотите использовать, по крайней мере, один раз в понятной компилятору манере. Например, я сделал простой SWC, содержащий символ с классом «TestCircle». В коде, который использовал SWC, у меня был следующий код, и он работал нормально:

import flash.utils.getDefinitionByName;

TestCircle;

var test:MovieClip =  new (getDefinitionByName("TestCircle") as Class)();

addChild(test);

Если вам хочется пофантазировать, вы можете написать небольшой скрипт, который взламывает SWC (это просто zip-файл), читает XML-манифест внутри и автоматически создает специальный класс «включающего». Но как говорится - оставлю читателю в качестве упражнения! ; -)

Надеюсь, это поможет!

4
ответ дан 8 December 2019 в 18:40
поделиться

Так что я все еще застрял при написании длинного, вручную созданного сценария, который ссылается на каждый импортированный класс. Допустим, строки намного короче, чем метод встраивания, даже на один член.

В конце концов, я создал свой ArtLibrary.fla, а затем просто скопировал и вставил все папки из библиотеки этого fla в каждую из 5 других моих fla. Я не стал компилировать файл swf. Для моих нужд это было наиболее эффективно.

Большое спасибо за помощь. Ваши ответы были прямыми и очень подробными.

0
ответ дан 8 December 2019 в 18:40
поделиться

Если вам захочется вообразить, вы можете написать небольшой скрипт, который взломает SWC (это просто zip ), прочтите XML-манифест, который находится внутри, и автоматически создайте специальный класс "включающего" . Но, как говорится, я оставлю это как упражнение для читателя ! ; -)

Не нужно делать ничего такого сложного (к счастью!). Аргумент компилятора include-libraries автоматически включает все классы из SWC, позволяя методу getDefinitionByName работать должным образом.

В вашем файле App-config.xml (или, альтернативно, переданном непосредственно в качестве аргумента компилятору):

<include-libraries>
    <library>path/to/your.swc</library>
</include-libraries>

Затем вы можете использовать getDefinitionByName как обычно.

HTH.

3
ответ дан 8 December 2019 в 18:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: