DroidScript
DroidScript
инструменты для мобильной разработки

Типы переменных

Базовый курс программирования на Thunkable X  
17.11.2019

Использование переменных в Thunkable X имеет ряд особенностей и нюансов, включая и само понятие типа переменной.

Глобальные переменные

Блоки app, stored и cloud называются глобальными, потому что они доступны на любом экране приложения. Если на экране Screen1 глобальной переменной app myVar присвоено значение 10, то на любом экране можно получить или изменить это значение при помощи блока переменной app myVar. Для изменения значения глобальной переменной необходимо в блоке переменной в точности указать её тип и имя. Переменные app myVar и stored myVar – разные переменные. У них не совпадает тип блока.

App-переменные предназначены для передачи данных между экранами. Их значения хранятся в оперативной памяти устройства и доступны только во время выполнения приложения. После закрытия приложения значения app-переменных будет потеряно. Для сохранения данных после завершения работы приложения и их повторного использования при следующем запуске приложения предназначены переменные stored или cloud.

Значение stored-переменной хранится на устройстве, а cloud – в облачной базе данных Firebase на аккаунте разработчика. Существует вероятность того, что эта база время от времени будет очищаться, что приведёт к удалению значений переменных. По этой причине рекомендуется использовать свой аккаунт Firebase. Для этого в проекте необходимо заполнить поля доступа к своей базе Firebase, после чего облачные переменные автоматически станут работать с ней.

Если в приложении необходимо организовать обмен данными между пользователями или  WebViewer, отправлять уведомления или обновления в приложение, вынести часть ресурсов из приложения в облако или совершать какие-то действия при изменении значения переменной, то в этом случае используется переменная типа cloud, для которой можно использовать блок прослушивания изменения её значения.

Облачная переменная с блоком прослушивания

Блок прослушивания появится в палитре Variables после добавления cloud-переменной на экран проекта. Вызов этого блока системой будет происходить независимо от того, где это изменение произошло, в самом приложении или в консоли Firebase. То есть, имя переменной name2 одновременно является путём к узлу в структуре базы данных Firebase и может содержать символ "/". Например, имя переменной users/count укажет для прослушивания узел count, родителем которого является узел users.

Если приложение открыто, то изменение значения cloud-переменной сразу приведёт к выполнению блока прослушивания. Если приложение закрыто, то блок прослушивания сработает при запуске приложения независимо от того, изменилось оно в базе или нет, так как блок прослушивания выполняется не только при изменении переменной, но и при её инициализации (присваивании первоначального значения), как это указано на блоке.

Блок прослушивания осуществляет прослушивание изменения значений всех дочерних узлов заданного узла. Например, если узел name2 содержит узел “0”, в котором находится узел “00”, то изменение значения узла ”00” приведёт к срабатыванию блока слушателя. Это не позволяет определить узел, в котором произошло изменение значения, если он имеет сложную структуру. Для определения узла, в котором произошло изменение, необходимо в cloud-переменной в точности указать путь к нему или использовать блок прослушивания компонента Realtime DB.

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

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

Stored-переменные не имеют блока для прослушивания и используются для сохранения персональной информации на устройство пользователя. Например, чтобы пользователь каждый раз не вводил логин и пароль для доступа к базам данных и web-сервисам, их сохраняют в stored-переменных. Thunkable X не позволяет создавать файлы, но вместо файлов можно использовать stored-переменные для сохранения настроек приложения и других данных, которые не предназначены для других пользователей.

Переменные из параметров функции

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

"Переменная из параметра функции" - это понятие, которое введено в употребление мной, и оно относится только к Thunkable X. В языках програмирование такого понятия нет.

В ранних версиях Thunkable X глобальных переменных не было и все переменные создавались из параметров функций. Это пиводило к путанице, так как по сути один и тот же механизм создания переменных позволял создать и глобальную переменную, и локальную. Для устранения этой путаницы и упрощения работы с переменными в Thunkable X были добавлены блоки глобальных переменных. Из-за ряда недостатков они не смогли заменить переменные из параметров функций.

Название "переменные из параметров функции" отражает тот факт, что блоки этих переменных создаются из параметров функций, после чего данные блоки становятся доступными даже после удаления блоков функции.

Переменные функции

Переменные из параметров функции в Thunkable X имеют ссылочный тип, чем принципиально отличаются от глобальных переменных app, stored и cloud. Ссылочный тип означает то, что в случае присоединения к этой переменной блока объекта, произойдёт сохранение в переменной ссылки на объект, а не копии этого объекта.

Предположим, у нас есть объект data, в котором хранятся имена и электронные адреса пользователей. Если блок этого объекта присоединить к переменной из параметра функции, то значением данной переменной будет не объект, а его адрес в оперативной памяти, например, 0000 0000 0010 0001. В этом случае переменная из параметра функции является ссылкой (указателем) на объект и они становятся как бы связанными друг с другом верёвкой. Если изменить свойства объекта в переменной из параметра функции, то это приведёт к автоматическому изменению свойств исходного объекта, на который она указывает. Если изменить свойства исходного объекта, то это автоматически приведёт к изменению свойств объекта в переменной из параметра функции, которая указывает на него. А можно ли разорвать это связь? Можно. Для этого к блоку переменной из параметра функции достаточно присоединить любой другой блок.

Если же блок объекта присвоить переменной типа app, stored или cloud, то при этом в этих переменных будет сохранена копия объекта, и её изменение никак не повлияет на исходный объект, а изменение исходного объекта никак не повлияет на уже существующую его копию, как это происходит в примере ниже, где диалог Alert1 отобразит строку {"name":"Steve"}.

Демонстрация использования ссылок на объект и копии объекта

Ниже показан пример, в котором после изменения имени второго объекта из списка на Steve, произойдёт его изменение в списке refList, но не списке app objectList. Это происходт по той причине, что блок refObjectявляется ссылкой на второй объект из списка refList. Изменение свойства этого блока приводит к изменению свойства исходного объекта в списке.

Пример “Ref and copy”.

Демонстрация использования ссылок на объект и копии объекта

В блоке app copyObject содержится копия объекта, изменение свойства которого никак не влияет на объект в списке. Если необходимо заменить объект в списке на его копию, то необходимо перезаписать объект в списке на его копию.

Ссылки нужны для увеличения эффективности работы приложений. Копирование объектов – это достаточно медленная операция, которая требует ещё много памяти для хранения копий объектов (об этом мы поговорим позже). Попробуйте создать 50 копий кнопок при помощи блока Any clone, чтобы увидеть то, сколько времени эта операция требует даже на современных и мощных телефонах. Для копирования объекта нужно выделить место в памяти и скопировать все его данные. А при использовании ссылок ничего этого не требуется, потому что ссылка – это переменная, в которой хранится адрес объекта, а не он сам. Вы обращали внимание на то, как бистро происходит перемещении большого файла из одной папки в другую в пределах одного раздела жёсткого диска? Это происходит потому, что на самом деле изменяется указательно на него. Представьте то, что файл - это большой дом. Для переноса целого дома из одного места в другой потребуется очень много усилий и времени, и намного проще поменять указать на него. Насколько медленнее работают в Thunkable X глобальные переменные по сравнению с переменными из параметров функций? Примерно в 1000 раз.

Переменные из параметров функций могут использоваться как за пределами функции, так и внутри неё. Если блок переменной из параметра функции используется за пределами функции или внутри функции, в которой нет параметра с тем же именем, то данный блок автоматически становится глобальным в пределах экрана. Если же блок переменной из параметра функции используется внутри функции, в которой также есть параметр с таким же именем, то в этом случае данный блок становится локальным.

Локальный параметр и глобальная переменная из функции

Слева показан пример локального параметра:

Label1.Text = undefined
Label2.Text = undefined

Справа используется переменная из параметра функции:

Label1.Text = undefined
Label2.Text = 100

Объект передаётся в функцию по ссылке. Поэтому функция изменит значение его свойства и Label2.Text = 40.

Передача объекта по ссылке

Если в функции вместо блока изменения свойства объекта поместить блок из предыдущего примера set x < 40, то в этом случае Label2.Text = 12, так как внутри функции переменная х - локальная переменная.

Для превращения переменной внутри функции в локальную переменную необходимо в эту функцию добавить параметр с именем этой переменной. Это можно использовать для скрытия данных внутри функции. Получается какой-то фокус. Да, Thunkable X имеет недостаточно развитую функциональность по причине чего приходится использовать различные "фокусы".

Параметры функции можно использовать для передачи в функцию данных или для превращения переменной в локальную. Чтобы избежать путаницы оставляйте при вызове функции входы для локализации парематров открытыми (не присоединяйте к ним блок). Тогда будет видно, какие параметры используются для передачи данных а какие - для превращения переменных в локальные.

Параметры функции обратного вызова

Помимо блоков глобальных переменных и переменных из параметров функции существует ещё одна разновидность блоков - параметров функции обратного вызова (ФОВ). Это блоки светло-зелёного цвета, прикреплённые к фиолетовым блокам методов или желтым блокам обработчиков событий. Они являются локальными, доступны только для чтения и при помощи них осуществляется передача данных из системы в приложение. О функциях обратного вызова мы поговорим позже, а пока запомните то, что значения светло-зелёных блоков, присоединённых к фиолетовым или жёлтым блокам обработки событий, существуют только внутри этих блоков.

Во избежание разных неприятностей блоки параметров функции обратного вызова желательно вообще не трогать. Если нужно использовать этот блок, то сначала его копируют, а затем  перетаскивают копию для подключения к нужному блоку. Если необходимо использовать значение параметра ФОВ за пределами содержащего их блока, то её блок необходимо присоединить к блоку глобальной переменной или переменной функции.

Базовый курс программирования на Thunkable X  
© 2016-2018 Александр Страшко