webForumDet fria alternativet

Stänga for each objekt

.NETur .NET

6 svar · 251 visningar · startad av Erik Juhlin

Erik JuhlinMedlem sedan maj 200010 687 inlägg
#1

Behöver man stänga ett objekt man använder i en for each loop? Typ:

Dim rs As ADODB.Recordset, f As ADODB.Field

Set rs = ...

For Each f In rs.Fields
	MsgBox f.Name
Next f

Set rs = Nothing

Behöver man där lägga till Set f = Nothing på slutet?

PoffeMedlem sedan apr. 20022 743 inlägg
#2

Nej, det har jag aldrig hört talas om att man ska göra.

Nexus86Medlem sedan okt. 20023 030 inlägg
#3

Kan alltid vara bra att göra för att bruka mindre minne.

Erik JuhlinMedlem sedan maj 200010 687 inlägg
#4

Behövs det eller stängs objektet automagiskt i.o.m. att loopen är klar? :)

nikoMedlem sedan juni 20022 599 inlägg
#5

Behövs det eller stängs objektet automagiskt i.o.m. att loopen är klar?

Frågan är egentligen ganska förvirrande. f refererar till ett ADODB.Field inne i ett ADODB.Recordset (rs) och minnet det upptar kan inte avallokeras innan Recordsetet avallokeras. Det avallokeras istället samtidigt som recordsetet avallokeras

set f=nothing

blir alltså helt verkningslöst (men inte fel).

Förutom det, så är f som referens i vilket fall som helst ogiltig efter loopen.

Experiment:

Dim rs As ADODB.Recordset, f As ADODB.Field
Set rs = ...
For Each f In rs.Fields
	MsgBox f.Name
Next f
[blue]msgbox f is nothing[/blue]
Set rs = Nothing

Referensen nollas alltså av loopen själv.

Erik JuhlinMedlem sedan maj 200010 687 inlägg
#6

Jo, provade det själv och fick också att f var Nothing efter loopen. Känns ganska logiskt också att f objektet endast finns inne i loopen.
Var min chef som helt plötsligt fått för sig att man behöver stänga såna objekt. :)

nikoMedlem sedan juni 20022 599 inlägg
#7

Var min chef som helt plötsligt fått för sig att man behöver stänga såna objekt.

Nej, enumeratorfunktionen i fields-collectionen fixar det själv. Men i andra fall har nog din chef en poäng som inte riktigt framgår av mitt svammel ovan.

Dim rs As ADODB.Recordset, f As ADODB.Field
Set rs = ...

set f = rs.fields(0) 'Vi skapar en kopia av [i]referensen[/i] till första fältet i rs.
debug.print ObjPtr(f) = ObjPtr(rs.fields(0)) 'Ger true eftersom det är samma objekt och inte en klonad kopia.
Set rs = Nothing 'Vi nollar den enda referensen till recordsetet.
Debug.print f.Name 'Fungerar bra.
Debug.print rs.fields(0).Name 'Ger run-time error eftersom rs inte är en giltig referens.
set f = Nothing 'Vi nollar referensen till fältet.

Frågan som uppstår är alltså när recordsetet egentligen avallokeras i det här fallet? Utan att ha kollat närmare så är jag ganska säker på att det inte sker förrän f har nollats.

142 ms totalt · 3 externa anrop · v20260731065814-full.29ac60f6
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
139 ms — hämta tråd, inlägg och bilagor (db)