DroidScript
DroidScript
разработка мобильных приложений

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

Секреты Thunkable X  
23.05.2020

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

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

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

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

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

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

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

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

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

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

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

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

Блок прослушивания можно использовать и для оставшихся типов глобальных переменных - app и stored.

Блок прослушивания

Результатом выполнения показанных блоков будет список на экране:

100
4
4
4
4

Почему значение 100 идёт раньше остальных опций и почему все остальный опции равны 4, а не 1,2,3,4 как мы ожидали получить? Блок слушателя является медленным блоком, который выполняется ассинхронно, а цикл работает очень быстро. По этой причине сначала выполнятся все блоки в обработчике событий (и переменная app set станет равна 4), а затем начнёт выполняться блок слушателя, один раз для инициализации переменной, а остальные 3 раза - при изменении переменной в цикле. По этой причине сначала в список запишется значение 100.

Если перед блоком добавления в список значения 100 поставить блок задержки на 1 секунду, то тогда блоки слушателей успеют выполниться раньше и згначение 100 окажется в конце списка.

Всё сказанное выше говорит о том, что нужно быть внимательным при использовании асинхронных блоков.

Переменная app list является ссылкой на список, по причине чего все значения отобразятся в List Viewer, несмотря на то, что они добавляются после присваивания списка области просмотра List Viewer.

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

Какой объём данных можно сохранять в переменных, например, объем текста в текстовых блоках? К сожалению, на этот счёт не существует никакой официальной информации. Практика показывает, что блоки без какого-либо труда могут работать с данными размером 200-300 килобайт. Проблемы могут начаться при попытке работы с данными порядка 400-500 килобайт и выше, что может выражаться в виде самопроизвольного закрытия приложения для тестирования, либо в некорректных результатах блоков при попытке выполнения различных операций с аким большим объёмом данных. Не стоит забывать и о том, что многие устройства имеют всего один гигабайт оперативной памяти.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Label1.Text = undefined
Label2.Text = undefined

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

Label1.Text = undefined
Label2.Text = 100

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

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

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

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

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

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

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

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

Эти переменные являются локальными и доступны только для чтения. С их помощью осуществляется передача данных из системы в приложение. О функциях обратного вызова мы поговорим позже, а пока нужно запомнить то, что значения данных блоков определены только внутри содержащих их блоков..

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

Секреты Thunkable X  
© 2016-2020  Александр Страшко