Статьи

Все, что вы, возможно, хотели бы знать об импортозамещении *

* Не совсем все.


В дни AS2 можно было обойтись без необходимости писать оператор import , просто используя полное имя класса в теле класса (например, flash.display.Sprite а не просто Sprite ). Хотя при написании кода вы можете использовать полное имя класса, в AS3 требуются операторы import для каждого класса.

Таким образом, нет необходимости в написании полностью определенных имен классов, если только вы не используете два класса с одинаковым коротким именем в одном классе — возможно, если вы используете класс Camera Flash вместе с классом Camera библиотеки 3D.


Исключением из предыдущего правила является случай, когда используемый вами класс и класс, который вы пишете, находятся в одном пакете . Все классы в пакете неявно доступны друг другу без оператора import .

В любом случае, написать оператор import неплохо, потому что:


Перечисляя все ваши импорты, вы создаете своего рода манифест того, на какие другие классы опирается ваш класс для выполнения своей работы. Это может показаться тривиальной вещью, но эта информация может оказаться весьма полезной. Рассмотрим следующий класс ***:

01
02
03
04
05
06
07
08
09
10
11
12
package com.activetuts {
    import com.activetuts.SuperTrace;
    import com.activetuts.ActiveTween;
    public class QuickTip {
        public function QuickTip {
            var tracer:SuperTrace = new SuperTrace();
            tracer.log(«Quick Tip»);
            var tween:ActiveTween = new ActiveTween();
            tween.go();
        }
    }
}

*** Надеюсь, очевидно, что этот класс является иллюстративным, а не функциональным.

Если вы затем используете этот класс QuickTip , Flash автоматически удостоверится, что классы SuperTrace и ActiveTween также скомпилированы в результирующий SWF, поскольку вы использовали QuickTip , а QuickTip требует эти классы.

Достаточно просто, но теперь рассмотрим более реалистичные классы, которые используют десятки других классов. Если вам нужно знать, какие классы используются, быстрый взгляд на раздел import может дать вам хорошее представление. Это не исчерпывающее и даже немного вводящее в заблуждение, но вам будет сложно найти человека, который считает, что самодокументированный код — это плохо.


Существует распространенное заблуждение относительно идеи, что использование большого количества классов обязательно означает, что размер файла вашего SWF увеличится. Обычно это правда. Но любой класс, начинающийся с flash предоставляется Flash Player и не влияет на размер вашего SWF. Например, байт-код для Sprite содержится во Flash Player, и вы просто регистрируете тот факт, что вы будете использовать Sprite, а не связывать этот байт-код в SWF. Это своего рода смысл наличия Flash Player.

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

  1. Создайте новый FLA и связанный класс документов .
  2. В классе документа напишите минимум, необходимый для его фактического определения в качестве класса документа:

    1
    2
    3
    4
    5
    6
    7
    package {
        import flash.display.Sprite;
        public class Document extends Sprite {
            public function Document() {
            }
        }
    }
  3. Откройте Параметры публикации , нажав Option-Shift-F12 / Alt-Shift-F12 (или выбрав Файл> Параметры публикации …).
  4. Нажмите на вкладку « Flash ».
  5. В разделе « Дополнительно » установите флажок « Создать отчет о размере ».
  6. Кроме того, в разделе « Настройки SWF » установите флажок « Экспортировать SWC » и снимите флажок « Включить метаданные XMP » (этот последний параметр удаляет кучу метаданных из SWF, которые увеличивают размер SWF, а также делает беспорядок отчета о размере мы будем смотреть).
    The Publish Settings
  7. Нажмите Control / Command-Enter, чтобы проверить фильм .
  8. Нажмите Control / Command-B, чтобы открыть Bandwidth Profiler (также доступен в View> Bandwidth Profiler при просмотре SWF)
  9. Обратите внимание на количество байтов этого SWF-файла (у меня в данный момент 354 , ваш пробег может отличаться, но он будет находиться в этом поле). Обязательно запишите байты, а не килобайты. Запомните этот номер.
    Where to find the size of the SWF in bytes
  10. Закройте SWF.
  11. Отредактируйте свой класс документа, чтобы использовать кучу классов flash . Например:

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package {
        import flash.display.*;
        import flash.media.*;
        import flash.net.*;
        import flash.text.*;
        public class Document extends MovieClip {
            public function Document() {
                var l:Loader = new Loader();
                l.load(new URLRequest(«someasset.swf»));
                var tf:TextField = new TextField();
                var format:TextFormat = new TextFormat(«Verdana»);
                format.align = TextFormatAlign.CENTER;
                tf.defaultTextFormat = format;
                var v:Video = new Video();
                var s:Sound = new Sound();
                var channel:SoundChannel = s.play();
            }
        }
    }

    Мы используем довольно много классов, которые сами включают в себя еще больше классов. Все эти классы, тем не менее, являются flash классами.

  12. Проверьте фильм снова. Bandwidth Profiler должен все еще быть открыт с прошлого раза; если нет, откройте его снова.
  13. Обратите внимание на размер SWF: я сообщаю о 596 байтах с указанным кодом, увеличившись на 242 байта. Это немного, учитывая, что я использую MovieClip (который расширяет целый ряд других классов), Loader , URLRequest , TextField , TextFormat , TextFormatAlign , Video , Sound и SoundChannel . Это большая функциональность для 242 байтов.
  14. На панели «Вывод» вы увидите что-то вроде следующего (если вы использовали приведенный выше дословно код, вы также увидите ошибки звука и загрузки, но они не важны):

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    flash-test.swf Movie Report
    —————————-
     
     
    Frame # Frame Bytes Total Bytes Scene
    ——- ———— ———— ——
          1 598 598 Scene 1 (AS 3.0 Classes Export Frame)
     
     
    Scene Shape Bytes Text Bytes ActionScript Bytes
    ——- ———— ———- ——————
    Scene 1 0 0 546
     
     
    ActionScript Bytes Location
    —————— ———
                   546 Scene 1:Frame 1:Document

Этот тест должен проиллюстрировать, что, хотя мы использовали много классов, предоставляемых Flash, результирующий размер нашего SWF-файла сравнительно невелик. Доказательством этого является отчет о размере, в котором мы не видим записей ни для одного из встроенных классов. Мы видим наш класс Document но других классов нет, и этот один класс отвечает за все байты ActionScript.

Если это не достаточно доказательств для вас, не стесняйтесь расширить эксперимент. Вы можете добавить еще больше классов, обеспечиваемых Flash, измеряя при этом увеличение размера SWF-файла, которое по-прежнему зависит от размера байтов. Вы можете включить свои собственные классы и убедиться, что они появляются в списке классов, а также более очевидным образом повлиять на размер SWF. Например, я создал этот простой класс Test :

1
2
3
4
5
6
7
package {
    public class Test {
        public function Test() {
            trace(«TEST»);
        }
    }
}

Включая этот единственный 7-строчный класс, который сам не использует другие классы, увеличил мой тестовый SWF до 717 байт, увеличившись на 121 байт. Это увеличение составляет половину увеличения, которое мы видели при добавлении всех этих классов flash ; отношение байтов к функциональности должно указывать, что классы flash не скомпилированы в ваш SWF.

Также обратите внимание, что вы увидите дополнительную запись в отчете о размере для дополнительного класса; что-то вроде этого:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
flash-test.swf Movie Report
—————————-
 
Frame # Frame Bytes Total Bytes Scene
——- ———— ———— ——
      1 719 719 Scene 1 (AS 3.0 Classes Export Frame)
 
Scene Shape Bytes Text Bytes ActionScript Bytes
——- ———— ———- ——————
Scene 1 0 0 673
 
ActionScript Bytes Location
—————— ———
               179 Scene 1:Frame 1:Test
               494 Scene 1:Frame 1:Document

Мораль этой истории: не стесняйтесь использовать столько flash классов, сколько хотите ****. Они не влияют на размер вашего SWF-файла (хотя, конечно, код, который использует эти классы)

**** Помните, что компоненты и классы Flex не предоставляются Flash Player. Эти классы выглядят интегрированными, но если пакет не запускается с flash , он не предоставляется проигрывателем.


Я прошу прощения за двойной отрицательный *****, но это еще одно распространенное заблуждение, которое я хотел бы прояснить.

Сначала быстрое определение. Импорт подстановочных знаков выглядит следующим образом:

1
import flash.display.*;

Это делает доступными все классы в пакете flash.display . Это сокращение по сравнению с (например):

1
2
3
4
5
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Graphics;
import flash.display.Sprite;

Теперь заблуждение. Когда я говорю «это делает доступными все классы», я НЕ имею в виду, что каждый класс в этом пакете автоматически компилируется в ваш SWF. Я имею в виду, что любой класс в этом пакете доступен вам в форме короткого имени, когда вы пишете класс. Так что в предыдущем примере я был бы свободен написать это:

1
2
3
4
5
var sp:Sprite = new Sprite;
var g:Graphics = sp.graphics;
g.beginFill(0);
g.drawRect(0, 0, 100, 100);
sp.blendMode = BlendMode.MULTIPLY;

Этот код использует Sprite, Graphics и BlendMode, которые находятся в пакете flash.display, и все они должны быть импортированы. Любой подход имеет одинаковый результат. Не стесняйтесь использовать групповой импорт.

Опять же, простой эксперимент для тех, кто требует доказательств. Для этого эксперимента нам нужны классы без flash . Вам понадобятся внешние классы, написанные вами, или что-то вроде Papervision3D или TweenMax. Я не буду загружать и устанавливать эти пакеты, но для целей моего примера кода я буду использовать простой пакет из четырех классов, созданных для этой цели. Вы можете найти их вместе с тестовыми файлами в пакете загрузки, в папке «wildcard-import». Классы находятся в пакете library .

  1. Создайте новый FLA и связанный класс документа .
  2. В своем коде импортируйте один класс . Например:
    import library.One . import library.One .
  3. И обязательно используйте его , например, с
    var o:One = new One();
  4. Протестируйте фильм (нажмите Command-Return / Control-Enter или выберите «Управление»> «Тестировать фильм» ).
  5. Откройте Bandwidth Profiler с запущенным SWF (нажмите Command-B / Control-B или перейдите в « Просмотр»> «Bandwidth Profiler» )
  6. Обратите внимание на размер SWF (опять же, в байтах, а не в килобайтах).
  7. Закройте SWF
  8. Измените класс документа так, чтобы при импорте использовался подстановочный знак . Например:
    import library.*;
  9. Проверьте фильм снова.
  10. Обратите внимание на размер SWF. Он должен быть таким же, как в прошлый раз.
  11. Вы также можете включить отчет о размере (не забудьте включить параметр SWC и отключить параметр XMP), чтобы увидеть, какие классы компилируются.

Это должно указывать на то, что, хотя похоже, что мы импортируем все из пакета, мы на самом деле компилируем только те классы, которые фактически используем.

***** Нет, я не


В следующем гипотетическом примере:

1
2
3
4
5
6
7
8
package {
    import SuperTrace;
    import ActiveTween;
    public class QuickTip {
        public function QuickTip() {
        }
    }
}

Классы SuperTrace и ActiveTween импортируются. Но они никогда не используются в классе. Компилятор Flash обычно достаточно умен, чтобы понять это и определить, что эти два класса не нужно компилировать для класса QuickTip .

Конечно, если другой класс использует класс SuperTrace , он будет скомпилирован. Дело в том, что компилятор довольно хорошо умеет не включать ненужные классы в ваш SWF.

Вы можете доказать это, настроив тест, аналогичный предыдущим тестам: сравните как размер байта, так и отчеты о размере двух SWF-файлов, которые идентичны, за исключением использования импортированного класса. Вы можете увидеть такой пример, сравнив проекты «import-with-use» и «import-with-use», включенные в исходный zip-архив.

Если по какой-то причине вам необходимо обеспечить компиляцию классов SuperTrace и ActiveTween , даже если вы не используете их в этом классе, вы можете принудительно сделать это, просто сославшись на них в теле класса. Например:

01
02
03
04
05
06
07
08
09
10
package com.activetuts {
    import com.activetuts.SuperTrace;
    import com.activetuts.ActiveTween;
    public class QuickTip {
        public function QuickTip {
            SuperTrace;
            ActiveTween;
        }
    }
}

Этого достаточно, чтобы компилятор мог видеть их как необходимые классы, даже если строки не сильно влияют на выполнение кода.