如何在swift中等待ui委托
Posted
技术标签:
【中文标题】如何在swift中等待ui委托【英文标题】:how to wait for ui delegate in swift 【发布时间】:2015-12-22 08:09:38 【问题描述】:我想在我的 Swift 2.0 应用程序的许多地方创建简单的对象助手来发送短信,并在下一步中创建另一个助手(电子邮件、pdf 打开器等)
我创建简单的类:
import Foundation
import MessageUI
class SmsHelper: MFMessageComposeViewControllerDelegate
func sendSMS(body: String)
if (MFMessageComposeViewController.canSendText())
let messageVC = MFMessageComposeViewController()
messageVC.body = body
//messageVC.recipients = ["Enter tel-nr"]
messageVC.messageComposeDelegate = self;
AppDelegate().sharedInstance().getTopController().presentViewController(messageVC, animated: false, completion: nil)
else
//do some alert etc.
func messageComposeViewController(controller: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult)
sendSMSRsp(result, errorMsg: nil)
controller.dismissViewControllerAnimated(true, completion: nil)
print("sms didFinishWithResult")
在代码中我想这样做的任何地方:
class someAnotherClass
func someFunction()
let smsHelper = SmsHelper()
smsHelper.sendSms("some text")
所以短信 ios 编辑器已打开,但是当我想关闭它或发送时,它不会关闭,函数 messageComposeViewController(controller: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult)
我从未调用过并且应用程序因内存泄漏而崩溃,我知道原因:是因为 SmsHelper 对象在 ' someFunction' 在该函数结束作用域后删除,并且该对象为 nil,系统尝试在 nil 对象处调用 didFinishWithResult。我确认它:当我将 smsHelper 对象添加为“SomeClass”的成员时,它起作用了 - 调用了委托。
问题是:这样做的最佳做法是什么,添加成员对我来说不是一个选项,因为许多类都可以使用它,而且创建一个单例,appDelegate 成员我认为很愚蠢。如何在作用域函数结束时强制不删除对象?
【问题讨论】:
【参考方案1】:尝试使用单例方式:
class SmsHelper: MFMessageComposeViewControllerDelegate
static let sharedInstance = SmsHelper()
private init()
及用法:
SmsHelper.sharedInstance().sendSms('some text')
编辑: 如果你从抽象类中添加不同的 init 方法。
private override init(message: String)
super.init()
然后将定义更改为static let sharedInstance = SmsHelper(message:"smsHelper")
并不复杂。
对于您的委托,只需将其分配到 init
方法之外,在 UIViewController
viewDidLoad
中,
SmsHelper.sharedInstance().delegate = self
【讨论】:
它有效,但如果 SmsHelper 有一个带有自定义构造函数的父级,例如,当我有 3 个类:SmsHelper、PdfHelper、EmailHelper 和具有构造函数 Helper(body:String) 的抽象类 Helper 时,它可能会很复杂) ,我开始阅读有关 NSOperation 的内容,是否可以使用 NSOperation 呢? 对不起,我失去了你所说的,但为什么你需要抽象类?如果添加一些方法可以摆脱耦合。为什么不?所有的 Helper 都应该是 NSObject 的子类。仅从我的角度来看。如果这个答案有帮助,请采纳。 我看到他描述also creating a singleton, appDelegate member is I think quite stupid.
我解释说:我写了最简单的例子来创建关于***的明确问题 - 在我的真实代码中,需要抽象帮助类有两个原因:1)有一个带有调用者和构造函数的委托 Helper(delegate: SomeProtocol) 2) 有抽象方法来创建 JsonResponse f.ex 时发送或不发送短信我创建一个 JSON 并将其发送给委托由于某些原因。
查看我的编辑。不确定是否解决了您的“复杂”问题。【参考方案2】:
对我来说,这样做的方法是创建闭包的类型别名,然后存储此类型别名的可选变量。当您调用 sendSMS 时,您传入一个闭包并将其设置为您的变量。然后可以在委托中调用它,然后通过 sendSMS 的闭包传递它:
import Foundation
import MessageUI
class SmsHelper: MFMessageComposeViewControllerDelegate
let messageVC: MFMessageComposeViewController!
typealias SMSCompletion = (result: MessageComposeResult, errorMsg: NSError?) -> ()
var sendSMSRsp: SMSCompletion?
func sendSMS(body: String, completion: SMSCompletion)
sendSMSRsp = completion
if (MFMessageComposeViewController.canSendText())
messageVC = MFMessageComposeViewController()
messageVC.body = body
//messageVC.recipients = ["Enter tel-nr"]
messageVC.messageComposeDelegate = self;
AppDelegate().sharedInstance().getTopController().presentViewController(messageVC, animated: false, completion: nil)
else
//do some alert etc.
func messageComposeViewController(controller: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult)
sendSMSRsp?(result: result, errorMsg: nil)
controller.dismissViewControllerAnimated(true, completion: nil)
print("sms didFinishWithResult")
class SomeOtherClass
func someFunction()
let smsHelper = SmsHelper()
smsHelper.sendSMS("some text") (result, errorMsg) -> () in
【讨论】:
这段代码对我来说是一个优雅的解决方案,但它不起作用,'messageComposeViewController didFinishWithResult' 永远不会被调用。 这听起来像是一个问题,因为代理设置不正确。我认为您需要在函数之外创建MFMessageComposeViewController
,我会更改我的答案以适应。
当你回答时 - 我移到函数的 MFMessageComposeViewController 之外 - 仍然没有工作并崩溃,看起来 smshelper 对象在 sendSms 范围的末尾被删除。以上是关于如何在swift中等待ui委托的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中转换 Objective-C TOCropViewController 委托方法?