2010-03-30 2 views
3

В здравом мире, это работает, как ожидалось:Вспышка AS3/AIR: сравнение содержимого Screen.screens

var array:Array = ['a','b','c']; 
trace(array.indexOf(array[0])); // returns 0 

В безумном мире, это происходит:

trace(Screen.screens.indexOf(Screen.screens[0])); // returns -1 

... если Screen.screens - это Array доступных экземпляров Screen, почему этот массив не может дать точный indexOf один из своих собственных детей?

редактировать - Чтобы сделать это шаг вперед, проверить это:

for each(var i:Screen in Screen.screens){ 
for each(var j:Screen in Screen.getScreensForRectangle(this.stage.nativeWindow.bounds)){ 
    trace(i, j, i == j); // returns false 
    trace(i.bounds, j.bounds, i.bounds == j.bounds); // returns false 
} 
} 

По крайней мере один Screen перечисленных в Screen.screens должен быть идентичен Screen в Screen.getScreensForRectangle(this.stage.nativeWindow.bounds) - но даже если сравнить Screen.bounds, он все еще не совпадает, несмотря на то, что два объекта Rectangle имеют одинаковые размеры!

Безумие, дамы и господа! Вы даже не хотите видеть обходной путь я ставлю вместе (подсказка: она включает в себя сравнение значений Screen.bounds.toString() за содержание Screen.screens)

+0

Я знаю, «экран, экран, экранные точки экрана». Но я хотел привести настоящий пример. –

ответ

2

Это обоснованное предположение, но так как Screen.screens только для чтения, и (?) изменение массива, которое он возвращает, не влияет, я думаю, что это довольно безопасная ставка, что внутренне, каждый раз, когда вы вызываете его, Flash генерирует и возвращает новый массив объектов Screen (вместо того, чтобы хранить внутренний набор объектов Screen и предоставлять вам доступ к ним). Когда вы звоните:

Screen.screens.indexOf(Screen.screens[0]) 

вы делаете два отдельных доступов к Screen.screens, так что, если каждый из этих вызовов возвращает другой массив объектов, это легко понять, почему вы не можете найти никаких совпадений - потому что метод indexOf тесты для === равенства, поэтому два разных объекта Screen не будут совпадать, даже если они содержат информацию о том же физическом экране.

Решение состоит в том, чтобы захватить копию массива экранов и использовать его. Это нормально работает:

var scr:Array = Screen.screens; 
trace(scr.indexOf(scr[0])); // returns 0 
+0

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

+0

Я думаю, что это вообще-то, о чем следует опасаться при тестировании объектов для равенства ... указывает ли API на ссылку на тот же объект, что и в прошлый раз, или на новый объект, в конечном счете является деталью реализации API, которая всегда безопасна не иметь зависимости. В конце концов, вы действительно не заботитесь о том, имеете ли вы две ссылки на один и тот же объект, что вас беспокоит, относятся ли они к одному и тому же физическому экрану ... который в этом случае трудно определить, но семантически вы понимаете, что я имею в виду. ;) – fenomas

+0

Но, чтобы ответить на ваш вопрос, как правило, я бы предположил, что что-то вроде экрана, который является всего лишь совокупностью информационных свойств, скорее всего, будет отброшенным объектом. Что-то вроде NativeApplication.openedWindows, который дает вам очень сложные объекты NativeWindow, скорее всего, даст ссылки на постоянный объект.И после быстрого теста это выглядит так. Но лучше не полагаться на него, если вы можете избежать этого, конечно .. – fenomas