Một cách thích hợp để chấm dứt một chuỗi bằng cách sử dụng Delphi cho iOS trong quản lý ARC là gì?Delphi TThread dưới ARC (iOS) không được phát hành
Hãy ví dụ đơn giản này:
TMyThread = class(TThread)
protected
procedure Execute; override;
public
destructor Destroy; override;
end;
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
FThread: TMyThread;
public
end;
{ TMyThread }
destructor TMyThread.Destroy;
begin
ShowMessage('Destroy');
inherited Destroy;
end;
procedure TMyThread.Execute;
begin
Sleep(5000);
end;
{ TForm2 }
procedure TForm2.Button1Click(Sender: TObject);
begin
FThread := TMyThread.Create(TRUE);
FThread.FreeOnTerminate := TRUE;
FThread.Start;
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
ShowMessage(FThread.RefCount.ToString);
end;
procedure TForm2.Button3Click(Sender: TObject);
begin
FThread := nil;
end;
Ok, nhấn Button1 sẽ đẻ trứng một sợi. Sau khi thread được bắt đầu, nếu bạn nhấp vào Button2 nó sẽ hiển thị một giá trị RefCount của 3 !! Vâng, 1 là tài liệu tham khảo để biến FThread của tôi, và có 2 tài liệu tham khảo bổ sung mà TThread tạo ra trong nội bộ ... Tôi đã đào vào mã nguồn và phát hiện ra rằng RefCount được tăng lên ở đây:
constructor TThread.Create(CreateSuspended: Boolean);
ErrCode := BeginThread(nil, @ThreadProc, Pointer(Self), FThreadID);
if ErrCode <> 0 then
raise EThread.CreateResFmt(@SThreadCreateError, [SysErrorMessage(ErrCode)]);
{$ENDIF POSIX}
Và ở đây:
Vâng ... Sau khi hoàn tất (Trong trường hợp của tôi, sau 5 giây), RefCount sẽ giảm xuống 2 (Vì tôi đã đặt FreeOnTerminate thành TRUE, nhưng nếu tôi không đặt FreeOnTerminate thành TRUE, thì RefCount sẽ vẫn là 3).
Xem sự cố? Chủ đề là không bao giờ hoàn thành và destructor không bao giờ được gọi là, nếu tôi gọi FThread := nil
, sau đó, RefCount nên giảm từ 2 đến 1 (Hoặc từ 3 ... Điện thoại
Có lẽ tôi đang thiếu một cái gì đó bởi vì tôi đang sử dụng để làm việc với các chủ đề không có ARC ... Vì vậy, những gì tôi thiếu ở đây? Hoặc có lỗi trong triển khai TThread trong ARC không?
Có lẽ định nghĩa này của TThread
private class threadvar
FCurrentThread: TThread;
nên một cái gì đó giống như
private class threadvar
[Weak] FCurrentThread: TThread;
Không phải 'FCurrentThread' được phát hành trong trình hủy không? –
FCurrentThread là một biến threadvar lớp của TThread, nó không phải là một biến từ cá thể, mà là một biến lớp từ TThread. Biến này không bao giờ được lưu trữ. Đánh giá bởi mã, nó sẽ thay đổi nếu tôi sinh ra một sợi khác ... nhưng tôi chưa thử nghiệm Vì vậy ... Trình hủy chỉ của tôi không bao giờ được gọi là – Eric
Nó sẽ không thay đổi bằng cách sinh ra một luồng khác. Mỗi chuỗi hệ điều hành có phiên bản riêng của biến đó bởi vì đó là một luồng. Đó là tương đương TThread của GetCurrentThreadID. –