Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 23.10.2012, 21:25
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 1  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Attention Странная разница между публичным полем и сеттером / геттером

Сейчас писал интерактивную обучалку к игре, и наткнулся на одну очень неприятную особенность, которая украла у меня несколько часов жизни ). Больше похожую на баг в ас3. В общем, не знаю баг это или нет, но суть в следующем. Есть некий класс TrainingStep, который в упрощенном виде выглядит примерно так (в очень упрощенном виде):
Код AS3:
package training {
     public class TrainingStep {
            public var targetDo:Sprite = null; 
            public var finished:Boolean = false;
     }
}
Этих этапов может быть сколько угодно. Так вот, при их создании, если этап обучения предполагает щелчок по какомму-то спрайту, или его наследнику, то при создании этапа, переменной targetDo присваиватеся ссылка на этот объект.
Далее этап помещается в массив. И в другой функции, по энтерфрейму проверяется весь массив до первого не пройденного этапа. И вот тут то начинаются странности, которые не поддаются моей логике.

Если используется публичная переменная targetDo, то в цикле, при проверке ссылки на ней, вылетит обращение к объекту null.
Если же, изменить ее на приватную, для назначения использовать сеттер, а для получения геттер, то все нормально.
Код AS3:
package training {
     public class TrainingStep {
            private var _targetDo:Sprite = null; 
            public var finished:Boolean = false;
 
            public function set targetDo(value:Sprite):void {
                    _targetDo = value;
            }
            public function get targetDo():Sprite {
                   return _targetDo;
            }
     }
}
Вот так будет все замечательно.

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

Старый 23.10.2012, 21:30
alatar вне форума Посмотреть профиль Отправить личное сообщение для alatar Найти все сообщения от alatar
  № 2  
Ответить с цитированием
alatar
 
Аватар для alatar

блогер
Регистрация: Dec 2008
Адрес: Israel, Natanya
Сообщений: 4,740
Записей в блоге: 11
Маловато данных. Сделайте тестовый пример.
Пока похоже на глюк в коде.
__________________
משיח לא בא
משיח גם לא מטלפן

Старый 23.10.2012, 21:39
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 3  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Пока похоже на глюк в коде.
Нет, в коде глюка нет. Более того, я сам код, где это происходит, никак не меняю. Меняю исплючительно публичную переменную на сеттер / геттер.

Вот кусок функции, в котором этапы создаются:
Код AS3:
private function setUpTraning():void {
   var ts:TrainingStep = new TrainingStep(Clause.SELECT_SOLDIER, _mySquad);				
   ts.mouseRestrictor = new Rectangle(0, 0, 800, 350);
   ts.soldier = _gui.soldierHolders[_gui.soldierHolders.length -1].soldier; 
   ts.targetDo = _gui.soldierHolders[_gui.soldierHolders.length -1]; // точно не null, и не зануляется в процессе
   ts.needsFocus = true;
   ts.needsTab = true;
   ts.keysText = "TAB + Щелчок левой кнопкой";
   _steps.push(ts);
}
А вот это вызывается по энтер фрейму:
Код AS3:
private function checkSteps():void{												
 
	var length:int = _steps.length;
	for (var j:int = 0; j < length; j++) {
		if (!_steps[j].finished) {
			if (_steps[j].window != null) {
				stage.addChild(_steps[j].window);
			}
			if (_steps[j].needsFocus == false) {
				FocusScreen.remove();
			}
			_steps[j].update();
			 if (_steps[j].endClause == Clause.SELECT_SOLDIER) {
				if (_steps[j].needsTab) {
					FocusScreen.needsSomeKey(Keyboard.TAB);
				}
				FocusScreen.text	= _steps[j].keysText;
				var targetPos:Point = (_steps[j].targetDo as Sprite).localToGlobal(new Point()); // если использовать паблик переменную, то здесь вылетит обращение к объекту null, если геттер, то все пройдет как по маслу
				targetPos.x 		+= _steps[j].targetDo.width / 2;
				targetPos.y 		+= _steps[j].targetDo.height / 2;
				FocusScreen.add(targetPos, 30);
			} 
			if (_emptyVehicleIcon.parent) {
				_emptyVehicleIcon.parent.removeChild(_emptyVehicleIcon);
			}
			break;
		} else {
			_steps[j].dispose();
			_steps.splice(j, 1);
			FocusScreen.remove();
			break;
		}
	}
}

Старый 23.10.2012, 22:03
alatar вне форума Посмотреть профиль Отправить личное сообщение для alatar Найти все сообщения от alatar
  № 4  
Ответить с цитированием
alatar
 
Аватар для alatar

блогер
Регистрация: Dec 2008
Адрес: Israel, Natanya
Сообщений: 4,740
Записей в блоге: 11
Цитата:
Если используется публичная переменная targetDo, то в цикле, при проверке ссылки на ней, вылетит обращение к объекту null.
Постоянно или периодически?

Добавлено через 2 минуты
P.S. Вас самого не напрягают постоянные обращения типа _steps[j] и _gui.soldierHolders[_gui.soldierHolders.length -1];? Даже если не принимать в расчет производительность.
__________________
משיח לא בא
משיח גם לא מטלפן

Старый 23.10.2012, 22:13
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 5  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
P.S. Вас самого не напрягают постоянные обращения типа _steps[j] и _gui.soldierHolders[_gui.soldierHolders.length -1];?
+1
Если постоянно строчить [].field - компилятор не увидит ошбки в написании field и не будет проверять его поля. Ну и код читабельнее без [].

По существу предположения 2:
- сделали описку в поле public var targetDo или при обращении к нему, а не упало потому что на MovieClip при определённых настройках компилятора можно динамически создавать поля (ничем не поддверждено, другого придумать не могу просто)
- бага компилятора

На сферическом примере в вакууме никакого бага нет:
Код AS3:
package training {
	import flash.display.Sprite;
     public class TrainingStep {
            public var targetDo:Sprite = null; 
            public var finished:Boolean = false;
     }
}
package {
	import flash.display.Sprite;
	import training.TrainingStep;
	public class Main extends Sprite {	
		public function Main():void {
			var sprite:Sprite = new Sprite();
			sprite.graphics.lineStyle(2, 0xff0000);
			sprite.graphics.drawEllipse(0, 0, 100, 80);
			var step:TrainingStep = new TrainingStep();
			step.targetDo = sprite;
			addChild(step.targetDo);// Круг добавляет, не падает
		}
	}
}
Т.е. надо пытаться воспроизвести баг на небольшом примере, либо констатировать, что он трудновоспроизводимый
Т.е. пытаемся вручную в приложении присвоить этому полю недачливый спрайт, посмотреть пропала ли бага, если _не_ пропала, попробовать присвоить другой спрайт и так пока не будет достигнут минимум, при котором бага ещё существует.


Последний раз редактировалось expl; 23.10.2012 в 22:31.
Старый 23.10.2012, 22:29
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 6  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
P.S. Вас самого не напрягают постоянные обращения типа _steps[j] и _gui.soldierHolders[_gui.soldierHolders.length -1];? Даже если не принимать в расчет производительность.
Нет, не напрягает. Код пишется на скорую руку. Оптимизировать буду потом. Сейчас мне интересна только природа этой ошибки.
Цитата:
сделали описку в поле public var targetDo или при обращении к нему, а не упало потому что на MovieClip при определённых настройках компилятора можно динамически создавать поля (ничем не поддверждено, другого придумать не могу просто)
Нет. Никакой описки нигде не сделал. Такую мелочь я бы сразу заметил. Да и не мувиклип там используется, а спрайт. Так что это предположение заведомо не верно.
Плюс к тому, когда преписываю геттер / сеттер, я просто добавляю к имени переменной андерскор, и в ФД жму ctrl + shift + 1 для автогенерации. Создается геттер и сеттер, с тем же именем. И все магическим образом начинает работать.
При обращении тоже никаких опечаток.
Цитата:
Постоянно или периодически?
Постоянно.

Старый 23.10.2012, 22:40
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 7  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
Нет, не напрягает. Код пишется на скорую руку
Что быстрее - строчить [i] или один раз набрать имя переменной - можно поспорить.
Цитата:
Нет. Никакой описки нигде не сделал. Такую мелочь я бы сразу заметил
Мне бы Вашу внимательность и уверенность в собственной точности,
Однако, моя версия действительно маловероятна.

А как насчёт попыток минимально воспроизвести багу?
Просто у меня не было таких проблем и сейчас вот набрал пример - всё работает.
Т.е Вам придется либо докопаться до Истины, либо забить, решить что произошла аномалия, что в остальных местах поле вместо гетера работает правильно

Старый 23.10.2012, 22:45
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 8  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Что быстрее - строчить [i] или один раз набрать имя переменной - можно поспорить.
Да согласен. Не нужно мне этого доказывать. Мне самому этот вариант не нравится, но в данный момент просто пофиг.
Цитата:
Т.е Вам придется либо докапаться до Истины
Придется. Мне не в лом использовать геттеры, но природное любопытство не позволит оставить все так

Цитата:
Мне бы Вашу внимательность и уверенность в собсвенной точности
Дело не в этом. Изначально я назвал переменную target, потом сделал рефакторинг, и во всех местах обращения они тоже переименовались. Соответственно ошибки в написании не было.

expl, у Вас пример не верный. Естественно она сразу же не отпадет. Отпадает при таком условии:
В одном методе создается объект, и его публичной переменной присваиватеся спрайт. Потом этот объект помещается в массив. А в другом методе, по энтер фрейму перебирается массив, и происходит попытка обращения к этой переменной.

п.с. Но на минимальном тесте не отваливается... Странно все это.
Буду копать дальше. Если обнаружу в чем проблема, отпишусь.

Добавлено через 15 минут
Да... Баг обнаружился. Глюк флешдевелоп, или флекс сдк. Сейчас еще раз проверил, все опять отвалилось. Закрыл ФД. Опять запустил, скомпилировал, заработало.


Последний раз редактировалось caseyryan; 23.10.2012 в 22:56.
Старый 24.10.2012, 10:49
gagaga вне форума Посмотреть профиль Отправить личное сообщение для gagaga Найти все сообщения от gagaga
  № 9  
Ответить с цитированием
gagaga
[+1 22.04.13]
[+1 06.03.13]

Регистрация: Apr 2012
Сообщений: 239
бывает... я как-то бился 3 часа, искал ошибку в своем коде и потом оказалось что adblock в браузере блокирует get запрос к серверу, потому что в урле содержится слово ads .... =)

Старый 24.10.2012, 11:10
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 10  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
У Flash IDE это постоянный прикол был с кэшированием. В ФД сталкивался два раза за всю историю отношений.. так что с первым причастием, caseyryan))))
__________________
Reality.getBounds(this);

Создать новую тему Ответ Часовой пояс GMT +4, время: 03:44.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 03:44.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.