По мотивам - http://programmingmindstream.blogspot.ru/2013/12/blog-post_3160.html
Что хочу сказать?
Одну ПРОСТУЮ ВЕЩЬ. Стоит ЛИШЬ посмотреть НОВЫЕ исходники от Embarcadero.
В частности FM.
Чтобы увидеть, что FreeAndNil - там ИСПОЛЬЗУЕТСЯ ПОВСЕМЕСТНО.
По-моему это - не "просто так".
По крайней мере это - "согласуется с МОИМ ЛИЧНЫМ ПРАКТИЧЕСКИМ опытом".
Вот "небольшой список" файлов:
V:\Embarcadero\Delphi\fmx\FMX.Ani.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.D2D.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.GDIP.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.GPU.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.GPU.Helpers.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Colors.pas
V:\Embarcadero\Delphi\fmx\FMX.Context.DX9.pas
V:\Embarcadero\Delphi\fmx\FMX.Context.GLES.pas
V:\Embarcadero\Delphi\fmx\FMX.Context.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Controls.pas
V:\Embarcadero\Delphi\fmx\FMX.Controls3D.pas
V:\Embarcadero\Delphi\fmx\FMX.Dialogs.pas
V:\Embarcadero\Delphi\fmx\FMX.Dialogs.Default.pas
V:\Embarcadero\Delphi\fmx\FMX.Edit.pas
V:\Embarcadero\Delphi\fmx\FMX.Effects.pas
V:\Embarcadero\Delphi\fmx\FMX.ExtCtrls.pas
V:\Embarcadero\Delphi\fmx\FMX.Filter.pas
V:\Embarcadero\Delphi\fmx\FMX.Filter.Effects.pas
V:\Embarcadero\Delphi\fmx\FMX.FontGlyphs.pas
V:\Embarcadero\Delphi\fmx\FMX.Forms.pas
V:\Embarcadero\Delphi\fmx\FMX.Forms.Border.pas
V:\Embarcadero\Delphi\fmx\FMX.Forms.Border.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Forms.Border.Win.pas
V:\Embarcadero\Delphi\fmx\FMX.Forms3D.pas
V:\Embarcadero\Delphi\fmx\FMX.Gestures.pas
V:\Embarcadero\Delphi\fmx\FMX.Gestures.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.Gestures.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Gestures.Win.pas
V:\Embarcadero\Delphi\fmx\FMX.Grid.pas
V:\Embarcadero\Delphi\fmx\FMX.Import.pas
V:\Embarcadero\Delphi\fmx\FMX.InertialMovement.pas
V:\Embarcadero\Delphi\fmx\FMX.Layers3D.pas
V:\Embarcadero\Delphi\fmx\FMX.Layouts.pas
V:\Embarcadero\Delphi\fmx\FMX.ListBox.pas
V:\Embarcadero\Delphi\fmx\FMX.ListView.pas
V:\Embarcadero\Delphi\fmx\FMX.ListView.Types.pas
V:\Embarcadero\Delphi\fmx\FMX.MagnifierGlass.pas
V:\Embarcadero\Delphi\fmx\FMX.Materials.Canvas.pas
V:\Embarcadero\Delphi\fmx\FMX.MaterialSources.pas
V:\Embarcadero\Delphi\fmx\FMX.Media.pas
V:\Embarcadero\Delphi\fmx\FMX.Media.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Media.Win.pas
V:\Embarcadero\Delphi\fmx\FMX.MediaLibrary.Actions.pas
V:\Embarcadero\Delphi\fmx\FMX.Memo.pas
V:\Embarcadero\Delphi\fmx\FMX.Menus.pas
V:\Embarcadero\Delphi\fmx\FMX.Messages.pas
V:\Embarcadero\Delphi\fmx\FMX.Objects.pas
V:\Embarcadero\Delphi\fmx\FMX.Objects3D.pas
V:\Embarcadero\Delphi\fmx\FMX.PhoneDialer.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.Pickers.pas
V:\Embarcadero\Delphi\fmx\FMX.Pickers.Default.pas
V:\Embarcadero\Delphi\fmx\FMX.Pickers.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.PixelFormats.pas
V:\Embarcadero\Delphi\fmx\FMX.Platform.pas
V:\Embarcadero\Delphi\fmx\FMX.Platform.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.Platform.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Platform.Win.pas
V:\Embarcadero\Delphi\fmx\FMX.Printer.pas
V:\Embarcadero\Delphi\fmx\FMX.StdActns.pas
V:\Embarcadero\Delphi\fmx\FMX.StdCtrls.pas
V:\Embarcadero\Delphi\fmx\FMX.Styles.pas
V:\Embarcadero\Delphi\fmx\FMX.TabControl.pas
V:\Embarcadero\Delphi\fmx\FMX.TextLayout.pas
V:\Embarcadero\Delphi\fmx\FMX.TextLayout.GPU.pas
V:\Embarcadero\Delphi\fmx\FMX.TreeView.pas
V:\Embarcadero\Delphi\fmx\FMX.Types.pas
V:\Embarcadero\Delphi\fmx\FMX.Types3D.pas
V:\Embarcadero\Delphi\fmx\FMX.Viewport3D.pas
V:\Embarcadero\Delphi\fmx\FMX.VirtualKeyboard.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.WebBrowser.pas
Или вот:
V:\Embarcadero\Delphi\databinding\components\Data.Bind.Components.pas
V:\Embarcadero\Delphi\databinding\components\Data.Bind.DBScope.pas
V:\Embarcadero\Delphi\databinding\components\Data.Bind.Grid.pas
V:\Embarcadero\Delphi\databinding\components\Data.Bind.ObjectScope.pas
V:\Embarcadero\Delphi\databinding\components\Fmx.Bind.Editors.pas
V:\Embarcadero\Delphi\databinding\engine\System.Bindings.Factories.pas
Ну или вот:
V:\Embarcadero\Delphi\Indy10\Protocols\IdAttachment.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAttachmentFile.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAttachmentMemory.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAuthentication.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAuthenticationDigest.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAuthenticationManager.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAuthenticationSSPI.pas
V:\Embarcadero\Delphi\Indy10\Core\IdBuffer.pas
V:\Embarcadero\Delphi\Indy10\Core\IdCmdTCPClient.pas
V:\Embarcadero\Delphi\Indy10\Core\IdCmdTCPServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCoder.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCoder00E.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCoderMIME.pas
V:\Embarcadero\Delphi\Indy10\Core\IdCommandHandlers.pas
V:\Embarcadero\Delphi\Indy10\Core\IdContext.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCookie.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCookieManager.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCustomHTTPServer.pas
V:\Embarcadero\Delphi\Indy10\Core\IdCustomTCPServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDateTimeStamp.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDICT.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDICTCommon.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDNSCommon.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDNSResolver.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDNSServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdEMailAddress.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdExplicitTLSClientServerBase.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFSP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPCommon.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListOutput.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseAS400.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseBase.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseDistinctTCPIP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseEPLF.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseIEFTPGateway.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseKA9Q.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseMicrowareOS9.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseMPEiX.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseMusic.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseMVS.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseNCSAForDOS.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseNovellNetware.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseNovellNetwarePSU.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParsePCNFSD.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseStercomOS390Exp.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseStratusVOS.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseTandemGuardian.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseTOPS20.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseTSXPlus.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseUnisysClearPath.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseUnix.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseVM.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseVMS.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseVSE.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseVxWorks.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseWfFTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseWindowsNT.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseXecomMicroRTOS.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListTypes.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPServer.pas
V:\Embarcadero\Delphi\Indy10\System\IdGlobal.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdGlobalProtocols.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdGopher.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHash.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHeaderCoderBase.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHeaderList.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHMAC.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHTTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHTTPHeaderInfo.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHTTPProxyServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHTTPWebBrokerBridge.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIcmpClient.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdIMAP4.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdIMAP4Server.pas
V:\Embarcadero\Delphi\Indy10\Core\IdInterceptSimLog.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIOHandler.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIOHandlerSocket.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIOHandlerStream.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIPAddress.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdIPAddrMon.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIPMCastClient.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIPMCastServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdIPWatch.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdIRC.pas
V:\Embarcadero\Delphi\Indy10\Core\IdLogFile.pas
V:\Embarcadero\Delphi\Indy10\Core\IdLogStream.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdLPR.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMailBox.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMappedFTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMappedPOP3.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMappedPortTCP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMappedPortUDP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessage.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageBuilder.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageClient.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoder.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoderBinHex4.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoderMIME.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoderQuotedPrintable.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoderUUE.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoderYenc.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCollection.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMultipartFormData.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdNetworkCalculator.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdNNTPServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdOTPCalculator.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdPOP3.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdPOP3Server.pas
V:\Embarcadero\Delphi\Indy10\Core\IdRawBase.pas
V:\Embarcadero\Delphi\Indy10\Core\IdRawFunctions.pas
V:\Embarcadero\Delphi\Indy10\Core\IdRawHeaders.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdRemoteCMDClient.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdRemoteCMDServer.pas
V:\Embarcadero\Delphi\Indy10\Core\IdReply.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdReplyIMAP4.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdReplySMTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSASL.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSASL_CRAM_MD5.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSASL_CRAM_SHA1.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSASLCollection.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSASLDigest.pas
V:\Embarcadero\Delphi\Indy10\Core\IdScheduler.pas
V:\Embarcadero\Delphi\Indy10\Core\IdSchedulerOfThread.pas
V:\Embarcadero\Delphi\Indy10\Core\IdSchedulerOfThreadPool.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdServerInterceptLogBase.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdServerInterceptLogFile.pas
V:\Embarcadero\Delphi\Indy10\Core\IdServerIOHandlerSocket.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSMTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSMTPBase.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSMTPRelay.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSMTPServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSNMP.pas
V:\Embarcadero\Delphi\Indy10\Core\IdSocketHandle.pas
V:\Embarcadero\Delphi\Indy10\Core\IdSocks.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSocksServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSSL.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSSLOpenSSL.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSSLOpenSSLHeaders.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSSLOpenSSLUtils.pas
V:\Embarcadero\Delphi\Indy10\System\IdStack.pas
V:\Embarcadero\Delphi\Indy10\System\IdStackBSDBase.pas
V:\Embarcadero\Delphi\Indy10\System\IdStackVCLPosix.pas
V:\Embarcadero\Delphi\Indy10\System\IdStackWindows.pas
V:\Embarcadero\Delphi\Indy10\Core\IdSync.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSysLog.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSysLogMessage.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSysLogServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSystatServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSystatUDPServer.pas
V:\Embarcadero\Delphi\Indy10\Core\IdTask.pas
V:\Embarcadero\Delphi\Indy10\Core\IdTCPConnection.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdTelnet.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdTelnetServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdText.pas
V:\Embarcadero\Delphi\Indy10\Core\IdThread.pas
V:\Embarcadero\Delphi\Indy10\Core\IdThreadComponent.pas
V:\Embarcadero\Delphi\Indy10\Core\IdThreadSafe.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdTrivialFTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdTrivialFTPServer.pas
V:\Embarcadero\Delphi\Indy10\Core\IdUDPBase.pas
V:\Embarcadero\Delphi\Indy10\Core\IdUDPClient.pas
V:\Embarcadero\Delphi\Indy10\Core\IdUDPServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdUserAccounts.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdVCard.pas
Для МЕНЯ ЛИЧНО - "вопрос про FreeAndNil" - ЗАКРЫТ.
Его НАДО использовать!
БЕЗДУМНО, если хотите.
И ЕЩЁ РАЗ сошлюсь на gunsmoker'а - http://www.gunsmoker.ru/2009/04/freeandnil-free.html
ЕЩЁ РАЗ цитата:
"Итак.
Так зачем же медлить? Почему бы, начиная с сегодняшнего дня, везде (где это возможно) использовать FreeAndNil вместо Free? Если вы сделаете это своей привычкой - вы ничего не потеряете, а, наоборот, приобретёте немалые бонусы.
Я не единожды сталкивался с трудно выловимыми багами в чужом коде со сложной иерархией классов. Потратив несколько часов на бесплодные попытки найти источник проблем "в лоб", просто тупо заменив все Free на FreeAndNil, проблема находилась сразу же (но вот над решением проблемы приходилось ещу долго думать).
Тем не менее, я подозреваю, что большинство людей, даже если они согласятся с приведённой выше аргументацией, не будут ломать свои привычки только по той причине, что "кто-то там что-то сказал". Они не встречались с такой ситуацией - значит, её нет (пока гром не грянет...). Как я уже сказал, FreeAndNil - это ремни безопасности. Пока какой-нибудь косяк не ударит вас сильно по носу, вы, скорее всего, не будете его использовать. Но уж будьте уверены, что когда он ударит - это будет весьма болезненно. Вы можете потратить на отладку кучу времени.
Примечание: всё вышесказанное является только моим мнением. Я просто высказал точку зрения и привёл её аргументацию. Следовать этой рекомендации или нет - целиком ваше решение и я приму его, какое бы оно ни было. Если вы признали, что подобная точка зрения имеет право на жизнь - моя задача выполнена."
ВСЁ! ЕЩЁ РАЗ - "для меня лично" - ВОПРОС ЗАКРЫТ.
Пожалуйста - не пытайтесь меня "троллить" по этому вопросу 1024-й раз...
Что хочу сказать?
Одну ПРОСТУЮ ВЕЩЬ. Стоит ЛИШЬ посмотреть НОВЫЕ исходники от Embarcadero.
В частности FM.
Чтобы увидеть, что FreeAndNil - там ИСПОЛЬЗУЕТСЯ ПОВСЕМЕСТНО.
По-моему это - не "просто так".
По крайней мере это - "согласуется с МОИМ ЛИЧНЫМ ПРАКТИЧЕСКИМ опытом".
Вот "небольшой список" файлов:
V:\Embarcadero\Delphi\fmx\FMX.Ani.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.D2D.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.GDIP.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.GPU.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.GPU.Helpers.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.Canvas.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Colors.pas
V:\Embarcadero\Delphi\fmx\FMX.Context.DX9.pas
V:\Embarcadero\Delphi\fmx\FMX.Context.GLES.pas
V:\Embarcadero\Delphi\fmx\FMX.Context.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Controls.pas
V:\Embarcadero\Delphi\fmx\FMX.Controls3D.pas
V:\Embarcadero\Delphi\fmx\FMX.Dialogs.pas
V:\Embarcadero\Delphi\fmx\FMX.Dialogs.Default.pas
V:\Embarcadero\Delphi\fmx\FMX.Edit.pas
V:\Embarcadero\Delphi\fmx\FMX.Effects.pas
V:\Embarcadero\Delphi\fmx\FMX.ExtCtrls.pas
V:\Embarcadero\Delphi\fmx\FMX.Filter.pas
V:\Embarcadero\Delphi\fmx\FMX.Filter.Effects.pas
V:\Embarcadero\Delphi\fmx\FMX.FontGlyphs.pas
V:\Embarcadero\Delphi\fmx\FMX.Forms.pas
V:\Embarcadero\Delphi\fmx\FMX.Forms.Border.pas
V:\Embarcadero\Delphi\fmx\FMX.Forms.Border.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Forms.Border.Win.pas
V:\Embarcadero\Delphi\fmx\FMX.Forms3D.pas
V:\Embarcadero\Delphi\fmx\FMX.Gestures.pas
V:\Embarcadero\Delphi\fmx\FMX.Gestures.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.Gestures.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Gestures.Win.pas
V:\Embarcadero\Delphi\fmx\FMX.Grid.pas
V:\Embarcadero\Delphi\fmx\FMX.Import.pas
V:\Embarcadero\Delphi\fmx\FMX.InertialMovement.pas
V:\Embarcadero\Delphi\fmx\FMX.Layers3D.pas
V:\Embarcadero\Delphi\fmx\FMX.Layouts.pas
V:\Embarcadero\Delphi\fmx\FMX.ListBox.pas
V:\Embarcadero\Delphi\fmx\FMX.ListView.pas
V:\Embarcadero\Delphi\fmx\FMX.ListView.Types.pas
V:\Embarcadero\Delphi\fmx\FMX.MagnifierGlass.pas
V:\Embarcadero\Delphi\fmx\FMX.Materials.Canvas.pas
V:\Embarcadero\Delphi\fmx\FMX.MaterialSources.pas
V:\Embarcadero\Delphi\fmx\FMX.Media.pas
V:\Embarcadero\Delphi\fmx\FMX.Media.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Media.Win.pas
V:\Embarcadero\Delphi\fmx\FMX.MediaLibrary.Actions.pas
V:\Embarcadero\Delphi\fmx\FMX.Memo.pas
V:\Embarcadero\Delphi\fmx\FMX.Menus.pas
V:\Embarcadero\Delphi\fmx\FMX.Messages.pas
V:\Embarcadero\Delphi\fmx\FMX.Objects.pas
V:\Embarcadero\Delphi\fmx\FMX.Objects3D.pas
V:\Embarcadero\Delphi\fmx\FMX.PhoneDialer.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.Pickers.pas
V:\Embarcadero\Delphi\fmx\FMX.Pickers.Default.pas
V:\Embarcadero\Delphi\fmx\FMX.Pickers.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.PixelFormats.pas
V:\Embarcadero\Delphi\fmx\FMX.Platform.pas
V:\Embarcadero\Delphi\fmx\FMX.Platform.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.Platform.Mac.pas
V:\Embarcadero\Delphi\fmx\FMX.Platform.Win.pas
V:\Embarcadero\Delphi\fmx\FMX.Printer.pas
V:\Embarcadero\Delphi\fmx\FMX.StdActns.pas
V:\Embarcadero\Delphi\fmx\FMX.StdCtrls.pas
V:\Embarcadero\Delphi\fmx\FMX.Styles.pas
V:\Embarcadero\Delphi\fmx\FMX.TabControl.pas
V:\Embarcadero\Delphi\fmx\FMX.TextLayout.pas
V:\Embarcadero\Delphi\fmx\FMX.TextLayout.GPU.pas
V:\Embarcadero\Delphi\fmx\FMX.TreeView.pas
V:\Embarcadero\Delphi\fmx\FMX.Types.pas
V:\Embarcadero\Delphi\fmx\FMX.Types3D.pas
V:\Embarcadero\Delphi\fmx\FMX.Viewport3D.pas
V:\Embarcadero\Delphi\fmx\FMX.VirtualKeyboard.iOS.pas
V:\Embarcadero\Delphi\fmx\FMX.WebBrowser.pas
Или вот:
V:\Embarcadero\Delphi\databinding\components\Data.Bind.Components.pas
V:\Embarcadero\Delphi\databinding\components\Data.Bind.DBScope.pas
V:\Embarcadero\Delphi\databinding\components\Data.Bind.Grid.pas
V:\Embarcadero\Delphi\databinding\components\Data.Bind.ObjectScope.pas
V:\Embarcadero\Delphi\databinding\components\Fmx.Bind.Editors.pas
V:\Embarcadero\Delphi\databinding\engine\System.Bindings.Factories.pas
Ну или вот:
V:\Embarcadero\Delphi\Indy10\Protocols\IdAttachment.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAttachmentFile.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAttachmentMemory.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAuthentication.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAuthenticationDigest.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAuthenticationManager.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdAuthenticationSSPI.pas
V:\Embarcadero\Delphi\Indy10\Core\IdBuffer.pas
V:\Embarcadero\Delphi\Indy10\Core\IdCmdTCPClient.pas
V:\Embarcadero\Delphi\Indy10\Core\IdCmdTCPServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCoder.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCoder00E.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCoderMIME.pas
V:\Embarcadero\Delphi\Indy10\Core\IdCommandHandlers.pas
V:\Embarcadero\Delphi\Indy10\Core\IdContext.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCookie.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCookieManager.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdCustomHTTPServer.pas
V:\Embarcadero\Delphi\Indy10\Core\IdCustomTCPServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDateTimeStamp.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDICT.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDICTCommon.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDNSCommon.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDNSResolver.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdDNSServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdEMailAddress.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdExplicitTLSClientServerBase.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFSP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPCommon.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListOutput.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseAS400.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseBase.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseDistinctTCPIP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseEPLF.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseIEFTPGateway.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseKA9Q.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseMicrowareOS9.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseMPEiX.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseMusic.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseMVS.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseNCSAForDOS.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseNovellNetware.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseNovellNetwarePSU.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParsePCNFSD.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseStercomOS390Exp.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseStratusVOS.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseTandemGuardian.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseTOPS20.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseTSXPlus.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseUnisysClearPath.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseUnix.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseVM.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseVMS.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseVSE.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseVxWorks.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseWfFTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseWindowsNT.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListParseXecomMicroRTOS.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPListTypes.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdFTPServer.pas
V:\Embarcadero\Delphi\Indy10\System\IdGlobal.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdGlobalProtocols.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdGopher.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHash.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHeaderCoderBase.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHeaderList.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHMAC.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHTTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHTTPHeaderInfo.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHTTPProxyServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdHTTPWebBrokerBridge.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIcmpClient.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdIMAP4.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdIMAP4Server.pas
V:\Embarcadero\Delphi\Indy10\Core\IdInterceptSimLog.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIOHandler.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIOHandlerSocket.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIOHandlerStream.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIPAddress.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdIPAddrMon.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIPMCastClient.pas
V:\Embarcadero\Delphi\Indy10\Core\IdIPMCastServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdIPWatch.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdIRC.pas
V:\Embarcadero\Delphi\Indy10\Core\IdLogFile.pas
V:\Embarcadero\Delphi\Indy10\Core\IdLogStream.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdLPR.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMailBox.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMappedFTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMappedPOP3.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMappedPortTCP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMappedPortUDP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessage.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageBuilder.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageClient.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoder.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoderBinHex4.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoderMIME.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoderQuotedPrintable.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoderUUE.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCoderYenc.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMessageCollection.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdMultipartFormData.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdNetworkCalculator.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdNNTPServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdOTPCalculator.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdPOP3.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdPOP3Server.pas
V:\Embarcadero\Delphi\Indy10\Core\IdRawBase.pas
V:\Embarcadero\Delphi\Indy10\Core\IdRawFunctions.pas
V:\Embarcadero\Delphi\Indy10\Core\IdRawHeaders.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdRemoteCMDClient.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdRemoteCMDServer.pas
V:\Embarcadero\Delphi\Indy10\Core\IdReply.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdReplyIMAP4.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdReplySMTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSASL.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSASL_CRAM_MD5.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSASL_CRAM_SHA1.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSASLCollection.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSASLDigest.pas
V:\Embarcadero\Delphi\Indy10\Core\IdScheduler.pas
V:\Embarcadero\Delphi\Indy10\Core\IdSchedulerOfThread.pas
V:\Embarcadero\Delphi\Indy10\Core\IdSchedulerOfThreadPool.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdServerInterceptLogBase.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdServerInterceptLogFile.pas
V:\Embarcadero\Delphi\Indy10\Core\IdServerIOHandlerSocket.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSMTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSMTPBase.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSMTPRelay.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSMTPServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSNMP.pas
V:\Embarcadero\Delphi\Indy10\Core\IdSocketHandle.pas
V:\Embarcadero\Delphi\Indy10\Core\IdSocks.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSocksServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSSL.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSSLOpenSSL.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSSLOpenSSLHeaders.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSSLOpenSSLUtils.pas
V:\Embarcadero\Delphi\Indy10\System\IdStack.pas
V:\Embarcadero\Delphi\Indy10\System\IdStackBSDBase.pas
V:\Embarcadero\Delphi\Indy10\System\IdStackVCLPosix.pas
V:\Embarcadero\Delphi\Indy10\System\IdStackWindows.pas
V:\Embarcadero\Delphi\Indy10\Core\IdSync.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSysLog.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSysLogMessage.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSysLogServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSystatServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdSystatUDPServer.pas
V:\Embarcadero\Delphi\Indy10\Core\IdTask.pas
V:\Embarcadero\Delphi\Indy10\Core\IdTCPConnection.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdTelnet.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdTelnetServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdText.pas
V:\Embarcadero\Delphi\Indy10\Core\IdThread.pas
V:\Embarcadero\Delphi\Indy10\Core\IdThreadComponent.pas
V:\Embarcadero\Delphi\Indy10\Core\IdThreadSafe.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdTrivialFTP.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdTrivialFTPServer.pas
V:\Embarcadero\Delphi\Indy10\Core\IdUDPBase.pas
V:\Embarcadero\Delphi\Indy10\Core\IdUDPClient.pas
V:\Embarcadero\Delphi\Indy10\Core\IdUDPServer.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdUserAccounts.pas
V:\Embarcadero\Delphi\Indy10\Protocols\IdVCard.pas
Для МЕНЯ ЛИЧНО - "вопрос про FreeAndNil" - ЗАКРЫТ.
Его НАДО использовать!
БЕЗДУМНО, если хотите.
И ЕЩЁ РАЗ сошлюсь на gunsmoker'а - http://www.gunsmoker.ru/2009/04/freeandnil-free.html
ЕЩЁ РАЗ цитата:
"Итак.
Так зачем же медлить? Почему бы, начиная с сегодняшнего дня, везде (где это возможно) использовать FreeAndNil вместо Free? Если вы сделаете это своей привычкой - вы ничего не потеряете, а, наоборот, приобретёте немалые бонусы.
Я не единожды сталкивался с трудно выловимыми багами в чужом коде со сложной иерархией классов. Потратив несколько часов на бесплодные попытки найти источник проблем "в лоб", просто тупо заменив все Free на FreeAndNil, проблема находилась сразу же (но вот над решением проблемы приходилось ещу долго думать).
Тем не менее, я подозреваю, что большинство людей, даже если они согласятся с приведённой выше аргументацией, не будут ломать свои привычки только по той причине, что "кто-то там что-то сказал". Они не встречались с такой ситуацией - значит, её нет (пока гром не грянет...). Как я уже сказал, FreeAndNil - это ремни безопасности. Пока какой-нибудь косяк не ударит вас сильно по носу, вы, скорее всего, не будете его использовать. Но уж будьте уверены, что когда он ударит - это будет весьма болезненно. Вы можете потратить на отладку кучу времени.
Примечание: всё вышесказанное является только моим мнением. Я просто высказал точку зрения и привёл её аргументацию. Следовать этой рекомендации или нет - целиком ваше решение и я приму его, какое бы оно ни было. Если вы признали, что подобная точка зрения имеет право на жизнь - моя задача выполнена."
ВСЁ! ЕЩЁ РАЗ - "для меня лично" - ВОПРОС ЗАКРЫТ.
Пожалуйста - не пытайтесь меня "троллить" по этому вопросу 1024-й раз...
Молчал-молчал, но раз уж ты эту тему так активно раз за разом поднимаешь, выскажусь наконец. Была у Льва Николаевича Толстого такая статья: "Не могу молчать" :)
ОтветитьУдалитьНе могу заставить себя серьезно воспринимать настолько детскую аргументацию:
Я не единожды сталкивался с трудно выловимыми багами в чужом коде со сложной иерархией классов. Потратив несколько часов на бесплодные попытки найти источник проблем "в лоб", просто тупо заменив все Free на FreeAndNil, проблема находилась сразу же (но вот над решением проблемы приходилось ещу долго думать).
Ты ведь понимаешь, что если бы он с самого начала использовал FreeAndNil, то об этом проблеме он бы даже НЕ УЗНАЛ и не стал бы ее решать? Это удобно конечно, успокаивает, но я о проблемах предпочитаю знать. Ты ведь понимаешь, что если Free без моего ведома повторно вызывается, то ситуация явно нештатная и неплохо бы о ней знать?
Я люблю эксепшены, эксепшены - лучшие друзья программистов. Если бы я не хотел их видеть, мой код бы выглядел вот таким образом (это куда надежнее, чем FreeAndNil):
try
// какой-то код
except
// пусто, ничего не делаем
end;
Но "спрятанные" эксепшены не избавляют тебя от багов. Программа не перестает неправильно работать. Зачем я это говорю, если для нас обоих это очевидно?
Я использую FreeAndNil в тех случаях, когда я сам допускаю, что Free может ШТАТНО вызываться более одного раза - иногда такое нужно. Но применять его ВСЕГДА? Брать это за ПРАВИЛО? Ну мы же взрослые люди, не будем пытаться закрывать уши ладошками и зажмуриваться вместо того, чтобы честно поймать свой эксепшен и НА САМОМ ДЕЛЕ РЕШИТЬ ПРОБЛЕМУ (да, это трудно, но программирование всегда было не для слабых духом) :)
P.S. Не хочу и не пытаюсь тебя троллить, но как я уже заметил - не смог промолчать. Если удалишь этот комментарий, не обижусь.
Ром, ну что делать - "твоя практика остаётся твоей практикой", а "моя практика остаётся моей".
Удалить"Доказывать" никому ничего не буду. Бестолку. Это я уже давно понял.
Зачем это было написано (в смысле пост)? Ну чтобы уж "перестали цепляться" к моим FreeAndNil. Только и всего.
А то ну прям на "каждый" FreeAndNil - находятся "любители откомментировать".
Про exception'ы ты пример хороший привёл, но по-моему к теме не относящийся.
"когда я сам допускаю, что Free может ШТАТНО вызываться более одного раза - иногда такое нужно" у меня почему то такое случается не "ИНОГДА", а "сплошь и рядом".
Я могу попытаться "объяснить почему":
1. У меня повсеместно используется подсчёт ссылок.
2. У меня используется кеширование экземпляров классов (и стандартных тоже).
Ну и "просто к слову" - я ЛИЧНО "изобрёл" FreeAndNil - когда его у Borland'а и в помине не было. Вот "почему-то" - "изобрёл". Не буду пытаться "поднять волны памяти", но думаю, что "не просто так".
Да, не будем спорить, смысла в этом мало. Просто захотелось высказаться, со мной такое бывает :) Надеюсь, ты не воспринял это слишком лично.
Удалить"Надеюсь, ты не воспринял это слишком лично. "
УдалитьНу скажем так - "рабочие моменты я стараюсь не воспринимать лично" :-) Хотя иногда - "заносит".
Всё же для меня - "работа - это жизнь".
Твои доводы мне - понятны.
Но поверь мне - я их уже не раз слышал :-)
Я попытался "аргументировать свою позицию". Но видимо - плохо выходит. Ну что делать.
Твой опыт - это твой опыт, мой опыт - это мой опыт.
Какой из них лучше? Да никакой :-)
Всё равно ведь - "программы работают" :-)
Может лет через 10-ть я пересмотрю свою позицию, ну или ты свою :-) так тоже - бывает.
Технологии же (и технологические приёмы) это не "предмет для спора",а "повод для обмена мнениями". ;-)
Вдогонку...
УдалитьВот если бы вместе работали и результат твоей работы зависел бы от моей и наоборот - тогда бы я СПОРИЛ бы :-)
Но там было бы гораздо меньше "абстрактных рассуждений". С обоих сторон.
"Но там было бы гораздо меньше "абстрактных рассуждений". С обоих сторон."
Удалить-- ну в смысле "поле для спора" сильно сузилось бы. До конкретных примеров.
А так - я не знаю твоей специфики, а ты моей.
Что собственно и подогревает бесконечные "интернет-холивары". Ну я не про наш с тобой случай. А так - "к слову".
Кстати про "воспринять слишком лично".
УдалитьИногда для "поддержания хороших отношений" полезно согласиться с оппонентом, особенно если ты "ему чего-то должен". Ну например он твой начальник. Ну или мама с папой. И перестать "критиковать его позицию".
Но! "Втихую" делать по-своему. А не пытаться "евангелировать". А если дело доходит до разборок "а почему ты так сделал" - аргументировать свою позицию. По каждому конкретному случаю. И либо "убедить" в ДАННОМ КОНКРЕТНОМ случае, либо признать, что в ДАННОМ КОНКРЕТНОМ случае был неправ.
А дальше уже идёт счёт "плюсов" и "минусов" по конкретным случаям и набирается статистика.
Ну понятное дело, что если "обе стороны" готовы "взаимодействовать", а не "просто спорить".
Но это уже опять же к вопросу о "сужении поля для спора". Не "вообще" всякие "кони в вакууме", а вполне "конкретные случаи".
"Ну например он твой начальник. Ну или мама с папой."
Удалитьну или ты "просто ценишь этого человека", но имеешь своё мнение и он тебя не убедил.
Да! Это просто из серии "заметок", а не в коем случае не из разряда "нравоучений".
УдалитьЯ наверное тут скорее просто "мысли вслух" озвучиваю.
Да, так просто закрыть тему не получится )
ОтветитьУдалитьЛично про себя: не сказал бы я, что я не любитель FreeAndNil. Но я не использую его повсеместно, я за то, чтобы его использовать везде, где это действительно надо (ну чтобы не писать две строчки Obj.Free; Obj := nil).
У FreeAndNil есть ещё одна особенность - сначала Nil, потом Free. Это даже хорошо, есть сценарии где это полезно, но сначала сбивает с толку.
P.S.: насчёт FM - я думаю, что там FreeAndNil используется именно для того, чтобы задействовать ARC. Вообще с введением ARC, который может быть то включен, то выключен - логично и правильно использовать только FreeAndNil.
насчёт FM - я думаю, что там FreeAndNil используется именно для того, чтобы задействовать ARC. Вообще с введением ARC, который может быть то включен, то выключен - логично и правильно использовать только FreeAndNil.
УдалитьЛогично и правильно работать по-старому, используя Free. На старых платформах это будет Free, а на новых превратиться в ":= nil" :)
не понял... предлагаешь повсеместно писать {$ifdef AUTOREFCOUNT} Obj := nil {$else} Obj.Free {$endif}?
Удалитьтогда уж лучше FreeAndNil(Obj), там директивы спрятаны внутри..
Посмотри как реализован Free, там уже все это написано.
УдалитьВидимо мы друг друга не понимаем. TObject.Free при включённом ARC не делает ничего, поэтому его вызов (для ARC) не несёт никаких последствий.
УдалитьЕсли я хочу, чтобы мой код работал и там, и там, я могу написать несколько вариантов:
а): Obj.Free; Obj := nil;
б): {$ifdef AUTOREFCOUNT} Obj := nil {$else} Obj.Free {$endif};
в) FreeAndNil(Obj);
Вот из этих всех трёх я бы предпочёл последний.
Он не не делает ничего. При компиляции Obj.Free автоматически заменяется на Obj := nil;
Удалитьprocedure TObject.Free;
begin
// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
if Self <> nil then
Destroy;
{$ENDIF}
end;
эээ... да, этого я недоглядел. И теперь понял смысл твоего комментария про "по-старому, используя Free".
УдалитьДействительно, Obj.Free с ARC работает как Obj := nil...
Это конечно хорошо, но выглядит это всё... прямо скажем не очень.
"Вообще с введением ARC, который может быть то включен, то выключен - логично и правильно использовать только FreeAndNil"
УдалитьВот вот :-)
"подсчёт ссылок"... Писал об этом выше. Только я "придумал" это почти на 20-ть лет раньше Embarcadero.
"У FreeAndNil есть ещё одна особенность - сначала Nil, потом Free."
УдалитьИ это - КРАЙНЕ правильно :-).
А если что-то не работает в этой парадигме, то это повод задуматься о том "какие объекты кем владеют". И "какие ссылки держат - сильные или слабые". И нет ли повода для "утечки ресурсов" или "провисших ссылок".
У меня когда-то был "скажем так" InvertedFreeAndNil. Ну для "таких случаев". Точнее l3FreeGlobalObject.
Но я от него - избавился в конце-концов.
И ещё...
Пока "ты работаешь один" и код "не сильно перемешивается", то Free или FreeAndNil - в общем всё равно. Но как только код "становится общим" - тут сразу появляется необходимость в использовании ИМЕННО FreeAndNil.
Ну что собственно Роман косвенно подтвердил словами "когда надо я пишу Free, а когда надо - FreeAndNil".
Только - тут становится не "я знаю", а "третий парень", а то и "десятый".
procedure l3FreeGlobal(var P);
Удалить{* - освобождает ГЛОБАЛЬНЫЙ объект со счетчиком ссылок и очищает переменную P ПОСЛЕ освобождения объекта.
Нужна для того, чтобы в процессе его освобождения была возможность обращаться к правильному экзаемпляру глобального объекта. }
l3FreeGlobal
Удалитьнаврал, что "совсем избавился". Сейчас посмотрел - используется в ОДНОМ только месте из ВСЕХ проектов.
Более того скажу - СТАНДАРТНАЯ ПРАКТИКА "разборок с проблемами в "чужом коде"" у "меня лично" начинается с "бездумной замены всех Free на FreeAndNil". Потом прогон всех возможных тестов тестов на предмет "а что поменялось". Потом прогон на "утечки памяти". И только ПОСЛЕ ЭТОГО - локализация и ОСМЫСЛЕНИЕ проблемы. И эта практика за ДОЛГИЕ ГОДЫ - себя БОЛЕЕ чем оправдывает.
УдалитьВреда для АРХИТЕКТУРЫ проектов и/или библиотек при замене Free на FreeAndNil - я пока не нашёл. Ни разу. При такой замене архитектура только "выправляется". При ОБРАТНОЙ замене - "возможны варианты".
Ну и ещё добавлю - FreeAndNil позволяет "автоматически" и на корню убивать подобные конструкции:
Удалитьf_SomeMyObject.SomeMyProperty.Free
или
f_SomeMyObject.SomeMyFunction.Free
которые (на МОЙ "вкус") - уж БОЛЕЕ чем "дурно пахнут".
"При такой замене архитектура только "выправляется"."
Удалить-- появляются "изолированные" singleton'ы, а не просто "глобальные объекты".
-- появляются связки publisher/subscriber, а не просто "объекты знают друг про друга".
-- появляются фабрики (и Dependecy Injection кстати), а не просто "давайте создадим объект, про котоый знаем "все кишки"".
-- появляются "кеши объектов", а не просто "давайте попробуем использовать объект повторно".
Что МЕНЯ лично только РАДУЕТ.
- появляется чёткое представление о том - "кто кем владеет". Кто держит "мягкую ссылку", а кто - "жёсткую".
УдалитьНу понятно, что всё что "я тут сказал" - это "абстрактные слова", не подкреплённые конкретными примерами. Ну вариантов тут несколько:
-- поверить мне на слово.
-- не согласиться.
-- задать вопросы о конкретных примерах.
-- наверное что-то ещё
:-)
"Ну и ещё добавлю - FreeAndNil позволяет "автоматически" и на корню убивать подобные конструкции:"
УдалитьЯ кстати не зря писал вот это - http://18delphi.blogspot.ru/2013/05/blog-post_7587.html
Рома правда и там со мной спорил.
Что ещё добавлю?
УдалитьНЕЛЬЗЯ "просто так" взять и "позвать на объекте метод Free". Для ЭТОГО надо обладать "объектной ссылкой". Да ещё и "жёсткой".
Было бы здорово, чтобы ЯЗЫК это КОНТРОЛЛИРОВАЛ.
ARC (да и "сборка мусора") - это ГАРАНТИРУЮТ, но к сожалению - не позволяют "экономить на спичках".
Кто ещё "гарантирует"?
Скажу - C++ с его статическими объектами (на стеке или в контексте других объектов) и Smart-Pointer'ами.
Понятное дело, что C++ это язык который "легко может позволить "выстрелить себе в ногу"".
Но! В отличии от Delphi, который вроде и БОЛЕЕ СИЛЬНО ТИПИЗИРОВАННЫЙ - C++ позволяет сделать так, чтобы "стрелять себе в ногу" и не захочется.
Этот комментарий был удален автором.
ОтветитьУдалить