Create(nil) Create(Self) Create(Application);

本文介绍了Delphi中三种创建对象的方法及其内存管理机制:Create(nil)、Create(Self)和Create(Application)。详细解释了每种方式如何处理对象的生命周期,并强调了Create(nil)需要手动释放内存,而Create(Self)和Create(Application)则会自动释放内存。

Create(nil);//需要自己释放   
Create(Self);//当Self释放时自动触发释放
Create(Application);//当Application释放时自动释放

Create(nil); 这种方式创建的对要自己手工进行FREE才会回收内存,其他很多内存泄漏就是忘了手工释放内存。
Create(Self);由self对象负责释放创建的对象,只self没有释放掉,这个对象的内存就不会被释入掉,除程序员手工进行释放,他会触发很多事件。性能不是很好。
Create(Application);
Create(Application.owner);
这两就是把self具体对象罢了  

 

补充:

X:=TX.create(XX);
那么当XX被释放时,XX会帮你释放X,这样你就不需要自己释放X了,如
Form1:=TForm1.create(Form2);
那么当Form2   free时,它就会自动帮你释放Form1,你就不用自己释放Form1了。
function TfmMaxinXs.AllDllTbsFmCreate(ADllFmName: TEnumFormName): Integer; var i: Integer; DllConfig: TDllConfig; DllHandle: THandle; GetFormClass: TGetDllFormClass; SetSharingParm: TSetSharingParm; FormClass: TFormClass; EmbForm: TForm; EmsRzTbs: TRzTabSheet; EmsDllInfo: TEmsDllInfo; EnumString: string; type TSynApp = procedure(APP: THandle); stdcall; begin Result := -1; // 初始化返回值(失败) EnumString := GetEnumName(TypeInfo(TEnumFormName), Integer(ADllFmName)); if Assigned(FAllEmsDllList) then begin if QueryFmIsCreateShow('tbs_' + EnumString) then // 简化QueryFmIsCreateShow参数 begin // ShowMessage(EnumString + ' 窗体已创建!'); Exit; end; end else FAllEmsDllList := TList<TEmsDllInfo>.Create; DllConfig.EnumFormName := TEnumFormName(-1); // 初始化无效值 for i := Low(DllConfigs) to High(DllConfigs) do begin if DllConfigs[i].EnumFormName = ADllFmName then begin DllConfig := DllConfigs[i]; Break; end; end; if DllConfig.EnumFormName = TEnumFormName(-1) then begin ShowMessage('未找到 ' + EnumString + ' 对应的DLL配置!'); Exit; end; DllHandle := LoadLibrary(PChar(DllConfig.DllName + '.dll')); if DllHandle = 0 then begin ShowMessage('加载 ' + DllConfig.DllName + '.dll 失败!' + SysErrorMessage(GetLastError)); Exit; end; var p: pDllParams; try try @GetFormClass := GetProcAddress(DllHandle, PChar(DllConfig.ExportFuncName)); if not Assigned(GetFormClass) then begin ShowMessage('在 ' + DllConfig.DllName + '.dll 中未找到导出函数 ' + DllConfig.ExportFuncName + '!'); Exit; end; var sysP: pSysParams; New(p); sysP := TSysParamsInfo.GetParamsData; p.ParamsStr := 'Testing'; p.LoginName := sysP.LoginName; p.dmACliHandle := sysP.dmACliHandle; p.sExePath := sysP.sExePath; FormClass := GetFormClass(application, Self.Handle, p, DllConfig.FmShowParm); if not Assigned(FormClass) then begin ShowMessage(DllConfig.DllName + '.dll 未能创建窗体类!'); Exit; end; Perform(WM_SETREDRAW, 0, 0); // 锁屏幕 RzPageControl1.DoubleBuffered := True; EmsRzTbs := TRzTabSheet.Create(application); EmsRzTbs.PageControl := RzPageControl1; EmsRzTbs.DoubleBuffered := True; EmbForm := FormClass.Create(application); EmbForm.ParentWindow := EmsRzTbs.Handle; // 必须使用ParentWindow,否则DLL消息处理不正常 EmbForm.WindowState := wsMaximized; EmsRzTbs.Name := 'tbs_T' + EmbForm.Name; EmsRzTbs.Caption := EmbForm.Caption; EmsRzTbs.Tag := EmbForm.Handle; // Integer(EmbForm); // 存储窗体实例指针(方便后续操作) EmbForm.FormStyle := fsNormal; EmbForm.BorderStyle := bsNone; EmbForm.Show; // ShowModal; RzPageControl1.Anchors := [akLeft, akTop, akRight, akBottom]; EmsDllInfo.DllHandle := DllHandle; EmsDllInfo.DllName := DllConfig.DllName + '.dll'; EmsDllInfo.DllTbsName := EmsRzTbs.Name; EmsDllInfo.FormHandle := EmbForm.Handle; EmsDllInfo.DllForm := EmbForm; EmsDllInfo.DllTbsHandle := EmsRzTbs; FAllEmsDllList.Add(EmsDllInfo); RzPageControl1.ActivePage := EmsRzTbs; SetWindowPos(EmbForm.Handle, HWND_TOP, 0, 0, Width - RzGroupBar1.Width - 20, Height - 80, SWP_NOZORDER); Perform(WM_SETREDRAW, 1, 0); // 解锁屏幕并重画 RedrawWindow(Handle, Nil, 0, RDW_FRAME + RDW_INVALIDATE + RDW_ALLCHILDREN + RDW_NOINTERNALPAINT); Result := 0; // 成功 finally Dispose(p); GetFormClass :=nil; end; except on E: Exception do begin ShowMessage('创建 ' + EnumString + ' 窗体失败:' + E.Message); FreeLibrary(DllHandle); // 失败时释放DLL end; end; end; procedure TfmMaxinXs.RzPageControl1Close(Sender: TObject; var AllowClose: Boolean); var i, j: Integer; TempHandle: THandle; TempDllInfo: TEmsDllInfo; begin if RzPageControl1.ActivePageIndex > -1 then begin i := RzPageControl1.ActivePageIndex; TempHandle := RzPageControl1.Pages[RzPageControl1.ActivePageIndex].Tag; for j := 0 to FAllEmsDllList.Count - 1 do begin TempDllInfo := FAllEmsDllList.Items[j]; if TempDllInfo.FormHandle = TempHandle then begin // ******************写这段代码,是让界面不闪动**************** if RzPageControl1.PageCount - 1 > i then RzPageControl1.ActivePageIndex := i + 1 else begin if RzPageControl1.PageCount > 1 then RzPageControl1.ActivePageIndex := i - 1; end; if TempDllInfo.DllForm <> Nil then begin TempDllInfo.DllForm.ParentWindow:= 0; // EmsDllInfo.DllForm.Close; //加上这个会报错 TempDllInfo.DllForm.DisposeOf; TempDllInfo.DllForm := NIl; TempDllInfo.FormHandle := 0; end; RzPageControl1.Pages[i].DisposeOf;// .Free; FreeLibrary(TempDllInfo.DllHandle); TempDllInfo.DllHandle := 0; FAllEmsDllList.Delete(j); SetSysFocus(Self.Handle); Break; end; end; end; end; delphixe11开发的程序,第一个函数是多个dll对应不同的tabsheet页面调用,页面关闭时调用第二个函数,如果在第二个函数中加入加上这行 释放DLL的 FreeLibrary(TempDllList.DllHandle)语句,再次调用都关闭的DLL ,就是再次调用第一个函数时在EmsRzTbs := TRzTabSheet.Create(application);会报异常。 帮我分析如何代码修改解决。
最新发布
12-31
#import <UIKit/UIKit.h> #import <ReactiveObjC/ReactiveObjC.h> NS_ASSUME_NONNULL_BEGIN #pragma mark - Model @interface StoryScene : NSObject @property (nonatomic, copy) NSString *sceneTitle; @property (nonatomic, copy) NSString *visualDescription; @property (nonatomic, strong) NSArray<NSString *> *symbolicElements; @end @implementation StoryScene @end @interface DigitalTool : NSObject @property (nonatomic, copy) NSString *toolName; @property (nonatomic, copy) NSString *usageDescription; @property (nonatomic, strong) NSArray<NSString *> *appliedScenes; @end @implementation DigitalTool @end @interface InteractionPlan : NSObject @property (nonatomic, copy) NSString *platform; @property (nonatomic, strong) NSArray<NSString *> *engagementMethods; @end @implementation InteractionPlan @end #pragma mark - ViewModel @interface StoryViewModel : NSObject @property (nonatomic, strong) NSArray<StoryScene *> *scenes; @property (nonatomic, strong) RACCommand *loadScenesCommand; @end @implementation StoryViewModel - (instancetype)init { self = [super init]; if (self) { @weakify(self); _loadScenesCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id _) { @strongify(self); return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [self fetchScenesFromService]; [subscriber sendCompleted]; return nil; }]; }]; } return self; } - (void)fetchScenesFromService { StoryScene *scene1 = [StoryScene new]; scene1.sceneTitle = @"黑暗中的微光"; scene1.visualDescription = @"黑白基调牢房,霉变米饭特写"; StoryScene *scene2 = [StoryScene new]; scene2.sceneTitle = @"铁窗下的课堂"; scene2.symbolicElements = @[@"树枝笔", @"棉灰墨", @"半截铅笔"]; _scenes = @[scene1, scene2]; } @end @interface ToolViewModel : NSObject @property (nonatomic, strong) NSArray<DigitalTool *> *tools; @property (nonatomic, strong) RACSubject *toolSelectedSubject; @end @implementation ToolViewModel - (instancetype)init { self = [super init]; if (self) { _toolSelectedSubject = [RACSubject subject]; [self setupTools]; } return self; } - (void)setupTools { DigitalTool *tool1 = [DigitalTool new]; tool1.toolName = @"PikaLabs"; tool1.usageDescription = @"水墨晕染风格动画"; DigitalTool *tool2 = [DigitalTool new]; tool2.toolName = @"Runway Gen-3"; tool2.usageDescription = @"动态分镜特效"; _tools = @[tool1, tool2]; } @end #pragma mark - View @interface SceneCell : UICollectionViewCell @property (nonatomic, strong) UILabel *titleLabel; @property (nonatomic, strong) UIImageView *symbolImageView; - (void)configureWithScene:(StoryScene *)scene; @end @implementation SceneCell - (void)configureWithScene:(StoryScene *)scene { _titleLabel.text = scene.sceneTitle; _symbolImageView.image = [UIImage imageNamed:scene.symbolicElements.firstObject]; } @end @interface MainViewController : UIViewController @property (nonatomic, strong) StoryViewModel *storyVM; @property (nonatomic, strong) ToolViewModel *toolVM; @property (nonatomic, strong) UICollectionView *collectionView; @end @implementation MainViewController - (void)viewDidLoad { [super viewDidLoad]; [self setupCollectionView]; [self bindViewModels]; } - (void)setupCollectionView { UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new]; _collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout]; [_collectionView registerClass:SceneCell.class forCellWithReuseIdentifier:@"SceneCell"]; [self.view addSubview:_collectionView]; } - (void)bindViewModels { @weakify(self); [[_storyVM.loadScenesCommand execute:nil] subscribeCompleted:^{ @strongify(self); [self.collectionView reloadData]; }]; [_toolVM.toolSelectedSubject subscribeNext:^(DigitalTool *tool) { NSLog(@"Selected tool: %@", tool.toolName); }]; } #pragma mark - UICollectionViewDataSource - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return _storyVM.scenes.count; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { SceneCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"SceneCell" forIndexPath:indexPath]; [cell configureWithScene:_storyVM.scenes[indexPath.item]]; return cell; } @end #pragma mark - Coordinator @interface AppCoordinator : NSObject @property (nonatomic, strong) UINavigationController *navigationController; - (void)start; @end @implementation AppCoordinator - (void)start { MainViewController *mainVC = [MainViewController new]; mainVC.storyVM = [StoryViewModel new]; mainVC.toolVM = [ToolViewModel new]; _navigationController = [[UINavigationController alloc] initWithRootViewController:mainVC]; } @end #pragma mark - AppDelegate @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (nonatomic, strong) UIWindow *window; @property (nonatomic, strong) AppCoordinator *coordinator; @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { _window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; _coordinator = [AppCoordinator new]; [_coordinator start]; _window.rootViewController = _coordinator.navigationController; [_window makeKeyAndVisible]; return YES; } @end NS_ASSUME_NONNULL_END
08-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值