- GetBookmark – устанавливает закладку на текущую запись;
- BookmarkValid – проверяет, существует ли запись, на которую ссылается закладка;
- GotoBookmark – позиционирует курсор на запись, на которую ссылается закладка;
- FreeBookmark – освобождает системные ресурсы, используемые методом GetBookmark.
Var
q: TSDQuery;
bm: TBookmark;
begin
Try
bm := q.GetBookmark; // делаем закладку
// обрабатываем ds
Finally
If bm <> nil then
begin
If q.BookmarkValid(bm) then
q.GotoBookmark(bm);
q.FreeBookmark(bm);
end;
End;
end;
В Delphi 7 код FreeBookmark выглядит так:
procedure TDataSet.FreeBookmark(Bookmark: TBookmark);
begin
FreeMem(Bookmark);
end;
В Delphi 2010 он – просто заглушка:
procedure TDataSet.FreeBookmark(Bookmark: TBookmark);
begin
// No longer need to free bookmark since it's a TBytes now.
end;
Т.е. FreeBookmark в Delphi 2010 – это уже пережиток прошлого и вызывать его больше не нужно. Таким образом, исходный код становится проще:
Var
ds: TSDQuery;
bm: TBookmark;
begin
Try
bm := q.GetBookmark; // делаем закладку
// обрабатываем ds
Finally
If (bm <> nil) and q.BookmarkValid(bm) then
q.GotoBookmark(bm);
End;
end;
P.S. А вот справочную систему Delphi 2010 подправить, как всегда, забыли. В ней есть раздел "DB.TDataSet.FreeBookmark" с описанием процедуры и рекомендацией ее использования. А раздел "Marking and Returning to Records" содержит строку "FreeBookmark frees the memory allocated for a specified bookmark when you no longer need it. You should also call DB.TDataSet.FreeBookmark before reusing an existing bookmark." и пример, где используется FreeBookmark :)
FreeBookmark - виртульный метод, и он с хорошей вероятностью может понадобится для освобождения ресурсов специфичных для унаследованной реализации. Поэтому в большом проекте я бы не стал рекомендовать нарушать задекларированный в VCL контракт.
ОтветитьУдалитьНеверно,т.к. в общем случае Bookmark - это абстрактные данные, т.е. там может быть и обьект и OleVariant (как в ADO). В общем определяется реализацией TDataSet. По ADO кстати есть подозрение на утечку ресурсов:
ОтветитьУдалитьprocedure TCustomADODataSet.GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer);
begin
Initialize(POleVariant(Data)^);
POleVariant(Data)^ := PRecInfo(Buffer).Bookmark;
end;
Здеcь не хватает вызова Finalize для декремента ссылок на ole обьект...
procedure TDataSet.FreeBookmark(Bookmark: TBookmark);
begin
Finalize(POleVariant(Bookmark)^);
// or:
// POleVariant(Bookmark)^ := Null;
end;
Спасибо за инфу об ADO. Я отталкивался от стандартного TDataSet и от используемого мной TSDDataSet из SQLDirect. В SQLDirect переопределен только BookmarkValid.
ОтветитьУдалить