請問 try..finally, Pointer ,FreeAndNil 的問題 |
答題得分者是:ha0009
|
seaturn99
版主 發表:69 回覆:427 積分:214 註冊:2003-08-25 發送簡訊給我 |
前天我寫了一段 Code , 出現了一個很奇怪的現象 ..
其中 Parse Method 中出現了怪現象..
procedure TFileParser.Parse; var i,j,k: integer; NewRules: TArrRule; ParseRange: TParseRange; ParseRow : TParseRow; begin try if not Assigned(FParserResult) then FParserResult := TStringList.Create; ; if not Assigned(ParseRow) then ParseRow := TParseRow.Create(nil); FParserResult.Clear; // ParseRange := TParseRange.Create; NewRules := SpiltRanges; i := 0; k := 0; while i <= FParserSource.Count-1 do begin if k <= High(NewRules) then if (NewRules[k].Range.StartRow <= i 1) and (NewRules[k].Range.EndRow >= i 1) then begin ParseRange := NewParseRange(NewRules[k]); ParseRange.Parse; FParserResult.AddStrings(ParseRange.RangeResult); i := i (NewRules[k].Range.EndRow-NewRules[k].Range.StartRow) 1; Inc(k); FreeAndNil(ParseRange); continue; end; // Full Range Pattern for j:=0 to PatternCount-1 do begin ParseRow.SubjectStr := FParserSource.Strings[i]; ParseRow.Pattern := FPatterns[j]; if ParseRow.Parse then FParserResult.Add(ParseRow.ExportResult); end; // End of For Inc(i); end; // End of While finally SetLength(NewRules, 0); FreeAndNil(ParseRange); FreeAndNil(ParseRow); end; end;註: TArrRule 是一個 Record Array TParseRange,TParseRow 是兩個 Class FParserResult 是 TFileParser 的內部使用的 Object; 第一個問題: 紅色標出的部分,是我的疑問,我利用 break point,然後利用 F8 ,Shitf F7 逐行 Trace Code,發現紅色地方永不會執行,似乎, ParseRow 已經被 Assigned, 我在程式其他的地方有宣告相同名稱的 Object,但並沒有 Unit Scope 的全域宣告,都類似上面宣告的方式,在 Method 結束時,便 Free 掉 object... 我以為 ParseRow : TParseRow; 可以利用 Assigned Function 來確定是否已經 Create Instance,看來我的觀念待釐清.. 當然, ParseRow 沒有 Create Instance, 在 FreeAndNil(ParseRow) 出了錯誤.不過,我觀察到一個有趣的現象,就是他把我的 Form Destory 掉了... 程式還是繼續進行,但執行 Form 上的 Object 時就掛了 第二個問題: 我曾經看一篇文章說: SomeClass1 := TSomeClass.Create; SomeClass2 := TSomeClass.Create; try {do some code } finally SomeClass1.Free; SomeClass2.Free; end; 是不安全的寫法 .. SomeClass1 := TSomeClass.Create; try SomeClass2 := TSomeClass.Create; try {do some code } finally SomeClass2.Free; end; finally SomeClass1.Free; end; 建議這樣比較安全,不過這樣程式碼看起來亂多了,要是使用了兩三個 Object,就看到兩三層的 try..finally, 有沒有更好的方法?? 如果我寫成如下,是否跟不良範例一樣?? try SomeClass1 := TSomeClass.Create; SomeClass2 := TSomeClass.Create; {do some code } finally FreeAndNil(SomeClass1); FreeAndNil(SomeClass2); end; 第三個問題: procedure TTest.TestP var P:Poniter; begin New(P); {Dosomthing} end; 沒有使用 Dispose(P),離開 Method 後 P 會自動釋放嗎?? |
ha0009
版主 發表:16 回覆:507 積分:639 註冊:2002-03-16 發送簡訊給我 |
|
seaturn99
版主 發表:69 回覆:427 積分:214 註冊:2003-08-25 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |