0

我想创建简单的对象助手,以便在我的 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)我从未调用过的函数并且应用程序因内存泄漏而崩溃,我知道原因:是因为 'someFunction' 中的 SmsHelper 对象在结束后被删除此函数的作用域,并且此对象为 nil,系统尝试在 nil 对象处调用 didFinishWithResult。我确认:当我将 smsHelper 对象添加为“SomeClass”的成员时,它起作用了 - 调用了委托。

问题是:这样做的最佳实践是什么,添加成员对我来说不是一个选项,因为许多类都可以使用它,而且创建一个单例,appDelegate 成员我认为是很愚蠢的。如何在作用域函数结束时强制不删除对象?

4

2 回答 2

0

尝试使用单例方式来做到这一点:

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
于 2015-12-22T09:06:46.590 回答
0

对我来说,这样做的方法是创建闭包的类型别名,然后存储此类型别名的可选变量。当您调用 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

        }
    }

}
于 2015-12-22T10:07:02.960 回答