-
Постов
385 -
Зарегистрирован
-
Посещение
-
Победитель дней
14
Сообщения, опубликованные xenon54
-
-
Да я кажется уже разобрался.
Видимо правильное удаление объекта в этом примере будет выглядеть так:
for I := 0 to Form1.ComponentCount-1 do begin if Components[i] is TImage then if Components[i].Tag = 11 then begin t2 := TImage(Components[i]); t2.DisposeOf; t2.Parent := nil; t2 := nil; end; end;
Т.е. нужно выполнить следующее:
1. Удалить все ссылки на самого себя внутри объекта путем вызова деструктора через Free, но почему-то этого не достаточно, а вот DisposeOF справляется с поставленной задачей.
2. Удалить все ссылки уже непосредственно в проекте которые делал сам, это ссылка в списке Children'ов у Form1, ну и саму ссылку/переменную t2.
-
Вангую вопрос про платформу
-
-
Вместо "string" в record нужно использовать "array [0..49] of char".
TXSession = record name : array[0..49] of Char; name2 : array[0..49] of Char; end;
А вообще, не уверен что эта тема относится к FM, разве что для не мобильной платформы можно было бы использовать string[50].
-
Всем привет!
Вопрос вроде бы легкий, но ....
Накидал пример в котором есть структура(простейшая), массив из этих структур, ну и запись/чтение массива структур в/из файл(а).
В процедуре чтения все идет на ура, проверяю в отладчике, все делается как надо. Как только строка переходит на "end" этой процедуры, выскакивает "Invalid pointer operation".
Кому лень качать, вот часть листинга:
type TXSession = record name : string; name2 : string; end; XRecordArray = array of TXSession; ...... class procedure TXSessionClass.ReadTXSessions(var AXArray: XRecordArray); var FS : TFileStream; XSession : TXSession; i, arr_length : integer; begin FS := TFileStream.Create( 'Sess_arr.txt', fmOpenRead ); FS.Read(arr_length, SizeOf(integer)); SetLength(AXArray, 0); for I := 0 to arr_length-1 do begin FS.Read(XSession, SizeOf(TXSession)); SetLength(AXArray, Length(AXArray) + 1); AXArray[Length(AXArray)-1] := XSession; //AXArray := AXArray + [XSession]; end; FS.Free; FS := nil; end; //<-- Тут вываливается IPO
-
да, если только вы не используете API мобильной платформы.
-
2. Есть AndroidVirtualDevice ('X:\Users\Public\Documents\Embarcadero\Studio\15.0\PlatformSDKs\adt-bundle-windows-x86-20131030\sdk\tools\android.bat avd'), но он жутко тормозит.
-
P.S.: Первый пост нужно поправить, там первая ссылка неправильная.
-
Была такая идея, но это же самый что не на есть костыль, причем в самом важнейшем аспекте программирования как управление памятью... Хотелось бы реально разобраться дело во мне (я чего-то не понимаю в работе ) или ...
-
В первом способе "TALAssetsLibrary" не смог найти где описан этот класс.
Второй способ работает на ура, спасибо.
-
-
Сделал еще 1 эксперимент:
procedure TForm1.Button1Click(Sender: TObject); var i, j : Integer; t, t2 : TImage; begin for j := 0 to 200 do begin t := TImage.Create(Form1); t.Parent := form1; t.Width := 50; t.Height := 50; t.Bitmap.LoadFromFile( TPath.Combine(TPath.GetDocumentsPath, '1.jpg') ); t.tag := 11; t := nil; for I := 0 to Form1.ComponentCount-1 do begin if Components[i] is TImage then if Components[i].Tag = 11 then begin t2 := TImage(Components[i]); t2.Parent := nil; t2.Free; t2 := nil; end; end; end; end;
Я так понял что я правильно реализовал способ номер 2 из этой темы. При картинке размером в ~200кб приложение крашится после 2-х кликов по кнопке. А вот если Free заменить на DisposeOf, то хоть утыкайся, приложение живет. В этой теме говорится что DisposeOf "форсирует вызов деструктора, но не очищает память выделенную под объект". Что это значит? И почему описанный выше пример не освобождает память?
P.S.: Этот пример для Android, хотя я так понял в этом смысле поведение не отличается для IOS и Android.
-
procedure TForm1.Button1Click(Sender: TObject); var t : TImage; begin t := TImage.Create(Form1); Memo1.Lines.Add(IntToStr( t.RefCount ) ); t.Parent := form1; t.Width := 50; t.Height := 50; Memo1.Lines.Add(IntToStr( t.RefCount ) ); t.Bitmap.Assign(image1.Bitmap); Memo1.Lines.Add(IntToStr( t.RefCount ) ); t.tag := 11; Memo1.Lines.Add(IntToStr( t.RefCount ) ); end; procedure TForm1.Button2Click(Sender: TObject); var i : Integer; begin Memo1.Lines.Add('---------------------'); for I := 0 to Form1.ComponentCount-1 do begin if Components[i] is TImage then if Components[i].Tag = 11 then begin Memo1.Lines.Add(IntToStr( TImage( Components[i] ).RefCount ) + ' - ' + IntToStr( Components[i].Tag ) ); TImage( Components[i] ).Parent := nil; Memo1.Lines.Add(IntToStr( TImage( Components[i] ).RefCount ) + ' - ' + IntToStr( Components[i].Tag ) ); end; end; end;
Вот результат memo после одного клика по button1 и одного клика по button2:
5 7 7 7 ------------------------------ 9 - 11 10 - 11
После этого делаю еще 1 клик по button2 и получаю:
7 - 11 10 - 11
- Кто-нибудь может объяснить почему RefCount такой большой? Ведь по идее в самом начале на объект ссылается только сама переменная "T" и плюс ссылка в списке "components" у form1.
- После выхода из процедуры "button1click" локальная переменная(ссылка на объект) "T" уничтожается и ее можно не считать, я правильно понял?
- Почему RefCount равен не 2, а 7?
- Почему если в конце процедуры "button1click" написать "t := nil;" картинка пропадает с формы, ведь на нее куча ссылок если верить RefCount'у
- Как тогда правильно уничтожить такой объект?
Система IOS.
-
...\Samples\Object Pascal\Mobile Samples\User Interface\ListView
Например "SampleListViewMultiDetailAppearanceProject"
-
А конкретней есть информация что нужно изменить в этих файлах?
-
Правильнее наверное будет сказать на основе "TPresetItemObjects"
-
Дык понятное дело. Там просто VCL вырезали. Но разница в цене колоссальная.
-
Сам спросил, сам ответил...
В FMX.ListView в функции определения индекса итема по абсолютной координате клика на ListView почему-то заложено такое поведение ( возвращает индекс последнего элемента если клик пришелся на область, вертикальная координата которой больше чем начало последнего итема). Вот так исправляется:
function TCustomListView.FindItemAbsoluteAt(ViewAt: Integer): Integer; var Left, Right, Pivot, Value: Integer; begin UpdateItemLookups; if Items.Count < 1 then Exit(-1); if ViewAt < 1 then Exit(0); { if ViewAt >= FHeightSums[FHeightSums.Count - 1] then Exit(FHeightSums.Count - 1); } if ViewAt > FHeightSums[FHeightSums.Count - 1] + GetItemHeight( GetItemCount - 1 ) then Exit(- 1);
-
Скажите пожалуйста, это нормальное поведение TListView? Создаем обычный TListView, добавляем в него 1 итем. Тыкаем мышкой в область TListView, но ниже итема в любом месте и каким-то чудом выделяется самый нижний итем, в данном примере он всего один. Если так и задумано {censored} то как с этим бороться
-
-
Таки да, достаточно внести в эту строку "else if Filter(Item.Text) or Filter(Item.Detail) then" свои поля и они тоже будут фильтроваться. Спасибо.
-
Если я правильно понял (Вы сделали свой стиль для ListBoxItem и вставили туда свой RadioButton), то:
1. Вам нужно присвоить "stylename" для этого RadioButton в стиле, допустим назвали вы его "MyRB".
2. В обработчике событий ListBox'a - OnItemClick пишем:
procedure TForm1.ListBox1ItemClick(const Sender: TCustomListBox; const Item: TListBoxItem); var i : integer; begin for i := 0 to ListBox1.count-1 do ListBox1.ItemByIndex(i).StylesData['MyRB.IsChecked'] := False; Item.StylesData['MyRB.IsChecked'] := True; end;
-
Они вон чего изобрели. Цена, цена вменяемая...
-
А потом выйдет новая версия в которой будет переделан этот юнит и опять вспоминать что там было... {censored}
Очередной вопрос про удаление объектов в ARC
в Управление памятью
Опубликовано · Изменено пользователем xenon54
Накосяпорил с квотами/
P.S.: Жаль нет кнопки удаления своих сообщений.