如何解决为什么在Objective-C代码中将Swift对象声明/未声明为属性时,其行为会有所不同?
我有一些Swift类使用一些库来呈现ViewController
。在这里:
@objc class FloatingPanelAdapter: NSObject,FloatingPanelControllerDelegate {
@objc func present(vcToBeShown: UIViewController,vcToPresent: UIViewController) {
// init of panel from library
let panel = FloatingPanelController()
// setting vc that I want to display
panel.set(contentViewController: vcToBeShown)
// setting delegate
panel.delegate = self
// presenting
vcToPresent.present(panel,animated: true)
}
/// FloatingPanelControllerDelegate method
func floatingPanel(_ vc: FloatingPanelController,layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout? {
/// FullFloatingLayout is my custom class that implements FloatingPanelLayout. I can show it if you want.
return FullFloatingLayout()
}
}
这是我在上课时的用法:
- (IBAction)pressed:(id)sender {
FloatingPanelAdapter *fpAdapter = [[FloatingPanelAdapter alloc] init];
SomeViewController *vc = [[SomeViewController alloc] init];
[fpAdapter presentWithVcToBeShown:vc vcToPresent:self];
}
按下按钮时,我只初始化FloatingPanelAdapter
并使用它。 SomeViewController
已成功显示,但配置不正确。它以FullFloatingLayout
库的默认布局(不是我的FloatingPanel
)呈现。但是魔术是当我将我的fpAdapter
声明为属性时:
#import "ViewController.h"
/* --- Importing Swift into Objective-C -- */
#import "SamplesObjC-Swift.h"
/* --------------------------------------- */
@interface ViewController ()
@property FloatingPanelAdapter *fpAdapter;
@end
@implementation ViewController
- (IBAction)pressed:(id)sender {
self.fpAdapter = [[FloatingPanelAdapter alloc] init];
SomeViewController *vc = [[SomeViewController alloc] init];
[self.fpAdapter presentWithVcToBeShown:vc vcToPresent:self];
}
@end
现在我的SomeViewController
已完整展示,并且配置正确,FullFloatingLayout
。我不会在这里留下截图,因为没关系。我认为问题是我在这里没有正确使用Objective-C(我不太了解)。为什么表现不同?可能是什么问题?
解决方法
我认为问题是我在这里没有正确使用Objective-C(我不太了解)。为什么表现不同?可能是什么问题?
不,不是。问题出在内存管理上。
- (IBAction)pressed:(id)sender {
// here fpAdapter is created locally,so on quit this context it is destroyed
FloatingPanelAdapter *fpAdapter = [[FloatingPanelAdapter alloc] init];
SomeViewController *vc = [[SomeViewController alloc] init];
[fpAdapter presentWithVcToBeShown:vc vcToPresent:self];
}
// >> here fpAdapter.dealloc
fpAdapter
被破坏后,面板的delegate
变成nil
,因为它是weak
,因此不会保留对fpAdapter
的引用
panel.delegate = self // << here !!
因此,要使delegate
工作,您必须在fpAdapter
的生命周期中保持生存panel
。并使其具有属性正是
@interface ViewController ()
@property FloatingPanelAdapter *fpAdapter; // << keeps strong reference
尽管在哪里,但您必须在某个地方保留对fpAdapter
的引用!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。