4 Replies
      Latest reply on Aug 13, 2018 9:26 AM by TheCD
      Marl Level 1 Level 1 (0 points)

        I'm trying to use a function as a parameter in (duh) another function.

        The param function is a callback.

        I've got another function in the same class which matches the required format:

        I want to use deadCallback as a default for the param so the function myFunc doesn't *require* a callback param.

         

        If I leave the code: = self.deadCallback out the app compiles with no problem.

        If I include it I get a compile time error:
        "value of type (myClass) -> () -> (myClass) has no member deadCallback"

         

        What am I doing wrong?
        Can I do this?
        If so, how?

         

        class myClass {

            

             func myFunc(_ url: String, callback: @escaping (_ resp: String) -> () = self.deadCallback) {

                  //do something that might make a string

                  var myStr? = "blah blah blah" //this may be nil which is perfectly acceptable

                  if(myStr != nil) {

                       callback(myStr!)

                  }

             }

            

             func deadCallback(_ resp: String) {

                  return

             }

         

        }

        • Re: How? function as param with a default??
          TheCD Level 3 Level 3 (475 points)

          Just make the callback closure optional.

           

          In the example below, line 3 has an optional closure in the form of ((_ resp: String) -> Void)?, with the default value of nil. Line 7 uses callback?(myStr) to perform the callback only if it's non-nil.

           

          class MyClass {
          
              func myFunc(_ url: String, callback: ((_ resp: String) -> Void)? = nil) {
                  //do something that might make a string
                  var myStr: String? = "blah blah blah" //this may be nil which is perfectly acceptable
                  if let myStr = myStr {
                      callback?(myStr)
                  }
              }
          
          }
          
            • Re: How? function as param with a default??
              macnib Level 1 Level 1 (10 points)

              This works in a playground...

               

               

              class MyClass {
              
                typealias MyCallbacks = (_ resp: String) -> ()
              
                static let deadCallback:MyCallbacks = {
                     message in
                     print("Called deadCallback with \"\(message)\"")
                }
              
                func myFunc(_ url: String, callback: @escaping MyCallbacks = MyClass.deadCallback) {
                     //do something that might make a string
                     let myStr:String? = "blah blah blah" //this may be nil which is perfectly acceptable
                     if let s = myStr {
                         callback(s)
                     }
                }
              }
              
              
              let test = MyClass()
              test.myFunc("http://somewhere.com")
              
              
              let testCallback:MyClass.MyCallbacks = {
                message in
                print("Called testCallback with \"\(message)\"")
              }
              
              test.myFunc("http://somewhere.com",callback:testCallback)
              
              
              
              
            • Re: How? function as param with a default??
              OOPer Level 8 Level 8 (5,675 points)

              What version of Xcode are you using? My Xcode 9.4.1 shows use of unresolved identifier 'self'. (With fixing `var myStr?` to `var myStr: String?`.)

               

              What am I doing wrong?

               

              Default parameters for functions are evaluated from the caller's side, so you cannot use any sort of things which are available in the callee's context. You cannot use `self`.

               

              Can I do this?
              If so, how?

               

              TheCD's proposal is a very good alternative, or you can use a closure literal.

               

                  func myFunc(_ url: String, callback: @escaping (_ resp: String) -> () = {_ in}) {
                      //do something that might make a string
                      var myStr: String? = "blah blah blah" //this may be nil which is perfectly acceptable
                      if let myStr = myStr {
                          callback(myStr)
                      }
                  }