1 Reply
      Latest reply: Oct 3, 2016 4:11 AM by eskimo RSS
      dhamukrish Level 1 Level 1 (0 points)

        Hi,

         

        I need help to solve this error. Basically this was working fine in Swift 2.x and Swift 3 broken. Please advise.

        Note that below code is almost converted to Swift 3 but with below error.

         

        Error

        'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.

         

        Error Line: 7

        let kerr = task_info(name, flavor, UnsafeMutablePointer(infoPointer), &size)

         

        Here is the code snippet

        open class func getMemoryUsed() -> Float {
          let MACH_TASK_BASIC_INFO_COUNT = (MemoryLayout<mach_task_basic_info_data_t>.size / MemoryLayout<natural_t>.size)
          let name = mach_task_self_
          let flavor = task_flavor_t(MACH_TASK_BASIC_INFO)
          var size = mach_msg_type_number_t(MACH_TASK_BASIC_INFO_COUNT)
          let infoPointer = UnsafeMutablePointer<mach_task_basic_info>.allocate(capacity: 1)
          let kerr = task_info(name, flavor, UnsafeMutablePointer(infoPointer), &size)
          let info = infoPointer.move()
          infoPointer.deallocate(capacity: 1)
        
          if kerr == KERN_SUCCESS {
            let used_bytes: Float = Float(info.resident_size)
            let total_bytes: Float = Float(ProcessInfo.processInfo.physicalMemory)
            log.info("Used: \(used_bytes / 1024.0 / 1024.0) MB out of \(total_bytes / 1024.0 / 1024.0) MB (\(used_bytes * 100.0 / total_bytes)%)")
            return used_bytes / 1000000 /
          }
        }
        
        


        • Re: Swift 3 iOS Memory Usage for Monitoring
          eskimo Apple Staff Apple Staff (6,675 points)

          Mach, like many old school C-based APIs, plays fast’n’loose with typing.  Getting this to work with Swift 3’s stricter aliasing rules is tricky.  Honestly, I think you might be better off writing a C helper routine to do this and then calling that helper routine from Swift.

          However, to answer your direct question, here’s how to call task_info to get MACH_TASK_BASIC_INFO in Swift 3.

          func mach_task_self() -> task_t {
              return mach_task_self_
          }
          
          func getMegabytesUsed() -> Float? { 
              var info = mach_task_basic_info()
              var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
              let kerr = withUnsafeMutablePointer(to: &info) { infoPtr in
                  return infoPtr.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { (machPtr: UnsafeMutablePointer<integer_t>) in
                      return task_info(
                          mach_task_self(),
                          task_flavor_t(MACH_TASK_BASIC_INFO),
                          machPtr,
                          &count
                      )
                  }
              }
              guard kerr == KERN_SUCCESS else {
                  return nil
              }
              return Float(info.resident_size) / (1024 * 1024) 
          }
          

          Notes

          • Lines 1…3 expose mach_task_self_ via a function-based wrapper, as you’d expect in C.

          • Line 6 declares the output buffer on the stack as the correct type, mach_task_basic_info.

          • Line 7 calculates its size in terms of integer_t, which is how Mach IPC counts.

          • Line 8 gets its address as an UnsafeMutablePointer<mach_task_basic_info>.

          • Line 9 reinterprets that as a contiguous array of integer_t, which is what Mach IPC wants.

          Finally, be warned that the value returned by this function has limited utility.  It might be useful when debugging but it’s almost certainly a very bad idea to use in production code.  If you are using it in product code, please post back explaining what you’re using it for and I can explain why that’s a bad idea (-:

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"