2010-02-01 2 views
5

나는이 페이지를 우연히 만났습니다 Why shouldn’t I call Application​.CreateForm. 지금이 같은 일부 코드가 있습니다Application .CreateForm을 두 번 호출하지 않으려면 어떻게해야합니까?

SplashForm := TSplashForm.Create(Application); 
SplashForm.Show; 
SplashForm.Update; // force update 
Application.Initialize; 
Application.CreateForm(TClientData, ClientData); 
SplashForm.Update; // force update 
Application.CreateForm(TClientMainForm, ClientMainForm); 
Application.ShowHint := True; 

Application.Run; 
ClientMainForm.ServerConnected := false; 
FreeAndNil(ClientMainForm); 
FreeAndNil(ClientData); 

먼저 splashform가 만든 다음, 데이터 모듈 및 기본 폼을 지속됩니다. 이 페이지에는 Application.CreateForm을 두 번 호출해서는 안됩니다. 위의 코드를 변경해야합니까?

감사

답변

5

Application.CreateForm을 여러 번 사용하여 아무 문제가 없습니다. 그러나 이것은 코드 냄새가 될 수있는 각 양식에 대한 전역 변수를 도입합니다. 아쉽게도 IDE는 각 양식에 대해 하나씩 만듭니다. 원하는 경우 제거 할 수 있습니다.

더 좋은 방법은 필요할 때 양식을 만들고 준비 할 때 놓는 것입니다. 그래서 당신은 Application.CreateForm을 메인 폼으로 만 사용합니다.

메인 데이터 모듈은 메인 폼으로 생성 될 수 있습니다. 그러나 그것은 세계 일뿐만 아니라 단지 맛의 문제 일 수 있습니다.

질문에 답하기 위해 양식을 로컬로 생성하고 릴리스하여 Application.CreateForm을 피할 수 있습니다.

이 기사에서는 Application.CreateForm의 부작용에 대해 언급합니다 (첫 번째 완성 된 양식이 기본 양식 임). 기본 폼에서 Application.CreateForm을 사용하여 다른 폼을 만드는 경우 예기치 않은 부작용이 발생할 수 있습니다.

그래서 불쾌감을 피하려면 전화를 한 번만 사용해야합니다. 이는 하나의 글로벌 양식을 사용하여 수행됩니다.

+0

내가 IDE가 전역을 만들어 제거하는 것이 더 나은 스타일을 고려하지 않습니다 ... 메모리 사용을 최소화 . 이것들은 Delphi 애플리케이션의 작동 방식의 일부입니다. 이러한 "최적화"는 실제로 최적화되지 않은 IDE 생성 코드보다 "코드 냄새"가 더 큽니다. –

+4

@ 워렌 : 그 의견은 전혀 이해가되지 않습니다. 델파이 애플리케이션은 메인 폼 변수를 제외하고는 전역 변수 중 어느 것도 사용할 필요가 없으며 메인 폼에 대한 변수는 프로젝트 파일의 변수로 쉽게 대체 될 수 있습니다. 다른 단위이기 때문에 실제로 전역 변수가 아닐 수도 있습니다. – mghie

+0

나는 단순히 "당신이 원한다면 제거 할 수 있지만"그 구절을 좋은 생각으로 생각하지 않습니다. –

1

TClientData가 데이터 모듈이고 TClientMainForm이 양식 인 경우, 실제로는 필요없는 실제로는 두 개의 FreeAndNil 호출을 제외하고는 없습니다. 하지만 조심해. 이 롭 케네디는 자신의 게시물에 말한다대로 Application.CreateForm 뒤에 다른 일을하기 때문에 (그것은 MainForm 변수를 설정), 그래서 나는 다음과 같은 규칙에 따라 프로젝트 파일을 설정하는 권합니다 :

  1. 에서 Application.CreateForm으로 단일 호출을 사용하여 시작할 때 만들려는 모든 양식을 만듭니다. 일반적으로이 작업은 IDE에서 수행합니다.

  2. 프로젝트 파일에서 프로그램에서 동적으로 (필요할 때) 만들려는 양식을 제거하십시오. (프로젝트 | 옵션 | 양식 ...) - 에서 양식 만들기 '사용 가능한 양식'

  3. 에 '자동 작성 양식'에서 그들을 이동 TmyForm.Create (소유자)를 사용하여 코드 (등 .) 및 이 아닌Application.CreateForm (...). 제쳐두고, 양식을 자유롭게 할 것이라면, TmyForm.Create (nil) - 소유자에게 연락하지 않는 것이 더 좋습니다.

  4. 시작시 초기화을 수행하려는 경우 이미 작성된 양식/데이터 모듈에 연결된 프로젝트 파일에서 프로 시저/메소드를 가질 수 있으며 응용 프로그램을 실행하기 전에 실행할 수 있습니다.예를 들어

:

begin 
    Application.Initialize; 
    Application.MainFormOnTaskbar := True; 
    Application.CreateForm(TdmoMain, dmoMain); //<--this is a data module 
    Application.CreateForm(TfrmMain, frmMain); //<--this will became the main form 
    Application.CreateForm(TfrmAbout, frmAbout); 
    //... other forms created here... 
    frmMain.InitEngine; //<--initialization code. You can put somewhere else, according with your app architecture 
    Application.Run; 
end. 

는 이러한 방법으로 청소 프로젝트 파일을해야합니다 그리고 당신은 어느 것이 어느 정확히 알 수 있습니다.

HTH

+0

+1 PLAINTH의 답변은 대부분의 Delphi 개발자가 사용하는 기존 규칙을 설명하고 따르고 있습니다.그 외의 다른 것은 내가 "최소한의 놀라움의 원칙"이라고 부르는 것에 위배됩니다. –

1

나는 기사, 나는 주로 외부 민주주의 인민 공화국 파일 코드 생각했다 썼다합니다. 사람들은 IDE에서 생성 된 양식 작성 코드를 DPR 파일에서보고 양식을 일반적으로 작성하는 가장 좋은 방법이라고 생각하여 프로그램의 다른 곳에서 사용합니다. 때로는 주 양식의 OnCreate 이벤트 처리기에서이 프로그램을 사용하여 프로그램에 필요한 다른 양식을 만든 다음 프로그램의 기본 양식이 생각하는 바가 아니기 때문에 문제가 발생합니다.

제공 한 코드에서 CreateForm을 한 번만 호출하면 쉽습니다. 기본 양식과 다른 용도로 사용하십시오. 데이터 모듈은 기본 폼이 아니므로 CreateForm의 마법이 필요 없습니다.

SplashForm := TSplashForm.Create(Application); 
SplashForm.Show; 
SplashForm.Update; // force update 
Application.Initialize; 

// Change to this. 
ClientData := TClientData.Create(Application); 

SplashForm.Update; // force update 
Application.CreateForm(TClientMainForm, ClientMainForm); 
Application.ShowHint := True; 

Application.Run; 
ClientMainForm.ServerConnected := false; 

// Remove these. 
FreeAndNil(ClientMainForm); 
FreeAndNil(ClientData); 

소유하고 있지 않기 때문에 생성 한 개체를 실제로 해제하면 안됩니다. 그것들은 전역 Application 객체에 의해 소유되므로 FreeAndNil에 대한 두 개의 호출을 제거하십시오.

+0

주 양식이 작성되었다는 것을 알고 있으면 다른 양식을 마술처럼 기본 양식으로 변환 할 수 없습니다. 그 경고가 이해된다면 Application 객체가 그 시점 이후부터 수명을 관리하기를 원할 경우에만 .dpr 소스 파일이 아닌 다른 곳에서 Application.CreateForm을 호출하는 것이 좋습니다. 그러나 우리 중 많은 사람들이 응용 프로그램이 살아있는 한 오래 살아있는 양식을 원하고 해제 된 상태이므로 Application.CreateForm을 호출하는 것이 바람직한 동작입니다. 나는 그것을 "후기 양식 창조"라고 부르며, 나는 그것을 항상 사용한다. –

+1

주 양식은 * 주 양식으로 지정되기 전에 자체 코드를 실행할 수 있습니다. 문제가 발생하는 곳입니다. Application 객체가 수명을 관리하기를 원한다면 다른 객체를 만들 때와 마찬가지로 폼의 생성자를 호출 할 때 Owner 매개 변수로 지정하고 내 대답의 코드에서 설명했듯이. 실제로 다른 클래스의 인스턴스를 만드는 것과 동일한 경우 폼을 만드는 데 중요한 중요성을 지닙니다. CreateForm을 호출하는 유일한 이유는 Application.MainForm이 필요할 때입니다. –

0

추천하는 기사가 잘못되었습니다. Application.CreateForm을 여러 번 호출하는 데는 여러 가지 이유가 있습니다.

1) Datamodules : 항상 사용할 수 있도록 설정하는 것이 좋습니다. 이를 수행하는 가장 좋은 방법은 Application.CreateForm입니다. 예를 들어 몇 가지 테마 Datamodules을 가진 응용 프로그램을 알고 있습니다. 고객, 송장, 데이터베이스의 다른 영역을 처리하는 주소 &은 기능을 깔끔하게 캡슐화합니다. 이들 모두는 .dpr에서 생성됩니다.

2)로드가 크고 느립니다. &에서는 좋지 않은 생각이지만, 이러한 일은 지원 프로그래머가 상속합니다. 로드 시간을 스플래시 화면 업데이트와 함께 예제 코드와 똑같은 응용 프로그램 시작으로 이동하십시오. 사용자 응용 프로그램이 Microsoft Office에서 작업하는 동료의 스릴링 노력 덕분에 나머지 응용 프로그램에 대한 기대치를 낮추는 데 시간이 걸릴 것으로 예상합니다.

요약하면 코드가 괜찮습니까?하지만 FreeAndNil을 잃어 버릴 수도 있습니다. 그러나 작은 빠른 타격 대화 형 물건이 최고에 의해 호출됩니다

with TMyform.Create(nil) do 
try 
    //Setup 
    case ShowModal of 
    // Whatever return values you care about (if any) 
    end; 
finally 
    Free; 
end; 

짧은, 달콤한, 지점 &에

+0

링크 된 기사가 부정확하다는 주장은 사실 매우 틀린 것입니다. 당신이주는 * 이유 중 * 어떤 것도'Application.CreateForm()'을 호출하는 이유가 아닙니다. Re 1) 당신은''Application'을 포함한'Owner '를 전달하여 간단히''Create() 할 수 있습니다. Re 2) 당신은 메인 양식의'OnCreate' 이벤트에서 그 첫 번째 일을 할 수 있고 아무도 조금의 차이점을 볼 수 없습니다. – mghie

+1

양식을 여러 가지 방법으로 만들 수 있지만 설명하는 방법에는 명백한 이득이없는 추가 코드를 작성해야합니다. 왜 당신은 의도적으로 "비 델파이"방식으로 일을하고 싶습니까? IDE에서 폼이나 Datamodule을 생성한다면 Delphi는 런타임에 .dpr에 넣는 Application.Createform 문을 사용하여 유용하게 만들 수 있습니다. Delphi에서 16 년 동안 작업하면서 저는 Application.Createform이 본질적으로 비효율적이거나 저자의 주장 인 것처럼 보이는 응용 프로그램의 수명 동안 필요한 양식에 바람직하지 않음을 보여주는 어떠한 증거도 아직 보지 못했습니다. – mcottle

관련 문제