Перейти к содержанию
  • Регистрация

Slym

Пользователи
  • Публикаций

    41
  • Зарегистрирован

  • Посещение

  • Победитель дней

    5

Сообщения, опубликованные Slym


  1. Под андроид идет опция AUTOREFCOUNT - все объекты имеют счетчик ссылок...
    любое присваивание - это +/- ссылки, даже Free не честное:
    procedure TObject.Free;
    begin
    // under ARC, this method isn't actually called since the compiler translates
    // the call to be a mere nil assignment to the instance variable, which then calls _InstClear
    {$IFNDEF AUTOREFCOUNT}
      if Self <> nil then
        Destroy;
    {$ENDIF}
    end;
    т.е. Free ничего не делает!!!  - экземпляр остается в зомбирежиме (ты его убил а оно ходит) пока счетчик до 0 не до тикает.
    TObject(TreeItem);  - пытается найти методы подсчета ссылок (Это же объект!) и не находит т.к. это не объект вовсе.
    TTreeItem = record меняем на TTreeItem = class, честно создаем и не забываем убить, хотя под AUTOREFCOUNT - оно само должно помереть если циклической ссылочности нет.


  2. аяяй! Совсем разленились try юзать, все на RefCounting надеетесь...
    ну-ну... а под вендой мемлики плодятся :) (если файла нет -  Surf куда?)
    не-не... переделать! а то студенты накопипастят...
     

    procedure TBitmapAsyncLoader.LoadImageAsync(const AFilePath:string; Callback: TProc);
    begin
      TTask.Run(
        procedure
        var ABitmapSurface : TBitmapSurface;
        begin
          ABitmapSurface:=TBitmapSurface.Create;
          try
            if TBitmapCodecManager.LoadFromFile(AFilePath, ABitmapSurface, CanvasClass.GetAttribute(TCanvasAttribute.MaxBitmapSize)) and assigned(Callback) then
              TThread.Synchronize(nil, Callback);
          finally
            ABitmapSurface.Free;
          end;
        end);
    end;



     


  3. ну в общем воркеры имеются... например TTask и запускаются в пуле...
    и можно запускать много тасков и они из общего пула не вылезут и делать к примеру так:
    данный код не бест и может ломать пикчу, и поэтому вопрошаю кто как... пользую TBitmap а не Surface что тоже не оптимально, но обратно совместимо с vcl (в дефайн обернуть?)

    procedure LoadImageAsync(const Name:string; Callback: TProc<TBitmap>);
    begin
      TTask.Run(
        procedure
        var Bitmap:TBitmap;
        begin
          Bitmap:=TBitmap.Create;
          try
            Bitmap.LoadFromFile(ImagePath+Name);
            TThread.Synchronize(nil,
              procedure
              begin
                Callback(Bitmap);
              end);
          finally
            Bitmap.Free;
          end;
        end);
    end;
      
    procedure TmainForm.FormShow(Sender: TObject);
    begin
      LoadImageAsync('logo1.png',
        procedure(Bitmap:TBitmap)
        begin
          Image1.Bitmap.Assign(Bitmap);
          Image1.Invalidate;
        end);
      LoadImageAsync('logo2.png',
        procedure(Bitmap:TBitmap)
        begin
          Image2.Bitmap.Assign(Bitmap);
          Image2.Invalidate;
        end);
      LoadImageAsync('logo3.png',
        procedure(Bitmap:TBitmap)
        begin
          Image3.Bitmap.Assign(Bitmap);
          Image3.Invalidate;
        end);
    end;
    

     


  4. Доп вопрос в тему: Как вы с fs загружаете картинки?
    по тутору андрюши любой доступ к fs желательно поточить, а тут еще и декод... а декод можно параллелить на кучи ядер смартфона
    но все поголовно не заморачиваются и тупо LoadFromFile в главном потоке. как правильно? на косяки TBitmap в потоке тоже нарывался прозрачность портит/чернит
    1. допустим есть форма и TImage на ней, и в него надо положить logo.png
    2. тоже самое но 10-20 images (параллельный декод)
     


  5. У меня IPhone6 вдулся от постоянного висения на шнурке...
    Теперь правило вечером отключить... но нет! нет отладки - нет зарядки и садится в ноль!
    Теперь правило в понедельник всегда на зарядку...


  6. Не делайте слепое приведение типов...
     

    var JObj:TJSONObject;
    begin
      JObj:=TJSONObject(TJSONObject.ParseJSONValue('0'));
      try
        try
          if assigned(JObj) then
            JObj.AddPair('Access','violation');
        except
          ShowMessage('Surprise MF!: '+JObj.ClassName);
        end;
      finally
        JObj.Free;
      end;
    end;

    ParseJSONValue возвращает TJSONValue, и необходима или проверка типа или использование только в рамках TJSONValue чего в большинстве случаев вполне достаточно.


  7. procedure TForm2.Button1Click(Sender: TObject);
    var Iters:integer;
    begin
      Iters:=100000000;
      TThread.CreateAnonymousThread(
        procedure
        var
        i:integer;
        a:real;
        begin
         for i := 0 to Iters do
         begin
           a:=i/3;
           if i mod 1000000 = 0  then
           begin
             TThread.Queue(nil,
              procedure
              begin
                ProgressBar1.Value:=ProgressBar1.Value+1;
              end);
           end;
          end;
        end).Start;
    end;
    

    и не надо никаких доп классов...
    еще есть TTask... тоже полезно


  8. Procedure TServerConnectionTH.RecieveData();
    // сюда приходя данные со сканера
    //Data - это данные в виже TBytes
    //str - строка со считанным штрихкодом
    var
      Intent: JIntent;
      str:String;
    begin
      str:=TEncoding.UTF8.GetString(Data);
      Form1.DisplayR.Lines.Add(Str);
      Form1.DisplayR.GoToTextEnd;
      Intent := TJIntent.Create;
      Intent.setAction(StringToJString('com.google.android.c2dm.intent.RECEIVE'));
      Intent.putExtra(StringToJString('text'),StringToJString('1')); 
      Intent.putExtra(StringToJString('title'),StringToJString('1C')); 
      Intent.putExtra(StringToJString('data'),StringToJString(str)); 
      TAndroidHelper.Context.sendBroadcast(Intent);
    end;

     


  9. procedure TForm1.LoadImage(const AItem: TListViewItem; const AListItemImage : TListItemImage);
    Var AAsyncResult : IAsyncResult;
    begin
      if Not Assigned(AItem) or Not Assigned(AListItemImage) then
        exit;
      if AItem.Data['ImageState'].AsInteger <> ListViewItemImageEmpy then
        exit;
      if AItem.Data['ImageURL'].AsString.IsEmpty then
        exit;
      AItem.Data['ImageState']:=ListViewItemImageLoading;
    
      if not assigned(FHTTPClient) then exit;
    
      TMonitor.Enter(listview1);
      try
        AItem.TagObject:=
        FHTTPClient.BeginGet(
          procedure (const ASyncResult: IAsyncResult)
          Var AHTTPResponse : IHTTPResponse;
          begin
            if assigned(AItem.TagObject) then
            begin
              TMonitor.Enter(listview1);
              try
                AItem.TagObject:=nil;
              finally
                TMonitor.exit(listview1);
              end;
            end;
            if ASyncResult.IsCancelled then exit;
    
            AHTTPResponse:=THTTPClient.EndAsyncHTTP(ASyncResult);
            if AHTTPResponse.StatusCode <> 200 then
              exit;
            TThread.Queue(nil,
              procedure
              begin
                if Not Assigned(AItem) or Not Assigned(AListItemImage) then
                  exit;
                AListItemImage.BeginUpdate;
                AListItemImage.Bitmap:=TBitmap.Create;
                AListItemImage.Bitmap.LoadFromStream(AHTTPResponse.ContentStream);
                AListItemImage.EndUpdate;
                AItem.Data['ImageState']:=ListViewItemImageLoaded;
              end);
          end,
          AItem.Data['ImageURL'].AsString) as TBaseAsyncResult;
      finally
        TMonitor.Exit(listview1);
      end;
    end;
    
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    var
      i:integer;
      IResult:IAsyncResult;
    begin
      TMonitor.Enter(listview1);
      try
        for i:=0 to listview1.Items.Count-1 do
          if assigned(listview1.Items[i].TagObject) then
            (listview1.Items[i].TagObject as TBaseAsyncResult).Cancel;
      finally
        TMonitor.Exit(listview1);
      end;
    
      TMonitor.Enter(listview1);
      try
        for i:=0 to listview1.Items.Count-1 do
          if assigned(listview1.Items[i].TagObject) then
          begin
            IResult:=TBaseAsyncResult(listview1.Items[i].TagObject) as IAsyncResult;
            TMonitor.Exit(listview1);
            try
              THTTPClient.EndAsyncHTTP(IResult);
            except
            end;
            TMonitor.Enter(listview1);
          end;
      finally
        TMonitor.Exit(listview1);
      end;
    end;

     


  10. В 01.02.2019 в 14:42, Евгений Корепов сказал:

    К сожалению логика асинхронности HTTPClient упускает одну важную вещь - идентификацию полученного результата

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


  11. умрет потому что используется TThread.CreateAnonymousThread, 500 потоков это не шутка...
    переделать на TTask. TTask плодит ограниченное кол-во потоков.
    или вовсе отказаться от собственных потоков и отдать на откуп асинхронному запросу THTTPClient
    1 экземпляр THTTPClient может одновременно обслуживать несколько асинхронных запросов (4-8)
    HTTPClient.BeginGet
     


  12. Боролись как-то с артефактами отображения (мы их прозвали "крокодилами" из-за сходства на первом скриншоте с этим багом)...
    Могли отображаться также левые спрайты, или обрезки скролившихся контролов...
    Коллега выяснил что не надо трогать Form.Fill, из-за переключения в недрах FMX нативной и не нативной канвы: если нужен фон - брось Rect по контенту и в нем делай заливку...


  13. 1. для упрощения кода работы с JSON давно можно использовать сложные пути
    ABase64:=JSON.GetValue<string>('body.nextStep.pdf');
    2.  ну нельзя так: 

    AStreamSource.WriteBuffer(Pointer(ABase64)^, Length(ABase64) * 2);

    так безопасней AStreamSource:=TBytesStream.Create(TEncoding.UTF8.GetBytes(ABase64));

    3. И сохранять лучше сразу в TFileStream - меньше расход памяти 

    4. не забываем finally Free (их выше нету)... хоть оно и может AUTOREFCOUNT (а может и нет!), но правила хорошего тона никто не отменял


  14. Проблема в том что есть 2 TScrollContent, один в FMX.Layouts, другой в FMX.ScrollBox...
    поскольку пользуете TPresentedScrollBox, то разворачивайте неймспейс вручную и пишите if (Parent is FMX.ScrollBox.TScrollContent) then

×
×
  • Создать...