Утечка памяти, может быть моя проблема с указателями [swift] - PullRequest
0 голосов
/ 17 мая 2019

iOS 12.x Swift 5

Я использую сокеты, чтобы поговорить с другой коробкой, и я написал этот код, который, я думаю, имеет смысл.но я хотел уточнить у эксперта.Я спрашиваю, потому что я думаю, что у меня какая-то утечка памяти с этим приложением.И я подозреваю указатели, как и вы.Я наблюдаю за тем, как медленно работает память, которую он использует.

func sendMessage(message: String) {

    let data = message.data(using: String.Encoding.utf8, allowLossyConversion: false)!
    let dataMutablePointer = UnsafeMutablePointer<UInt8>.allocate(capacity: data.count)
    //Copies the bytes to the Mutable Pointer

    dataMutablePointer.initialize(to: 0)
    data.copyBytes(to: dataMutablePointer, count: data.count)

    //Cast to regular UnsafePointer
    let dataPointer = UnsafePointer<UInt8>(dataMutablePointer)

    //Your stream
    outputStream.write(dataPointer, maxLength: data.count)
    defer {
      dataMutablePointer.deinitialize(count: data.count)
    }
}

Этот код выглядит вменяемым?Может ли это быть источником моей утечки памяти?Нужно ли деинитализировать этот указатель?

1 Ответ

1 голос
/ 18 мая 2019

Может ли это быть причиной утечки моей памяти?

Да, конечно.

Нужно ли деинитализировать этот указатель?

Как прокомментировал bscothern, вам нужно деинитализировать указатель, если Pointee нетривиального типа. Но в случае UInt8 это не обязательно.

Но вам необходимо в конце концов освободить указатель .

Ваш код будет выглядеть примерно так:

func sendMessage(message: String) {

    let data = message.data(using: String.Encoding.utf8, allowLossyConversion: false)!
    let dataMutablePointer = UnsafeMutablePointer<UInt8>.allocate(capacity: data.count)
    defer {
        dataMutablePointer.deallocate()
    }

    //Copies the bytes to the Mutable Pointer
    dataMutablePointer.initialize(to: 0)
    defer {
        //This is not required, but you can put `deinitialize` here if you prefer
        dataMutablePointer.deinitialize(count: data.count)
    }
    data.copyBytes(to: dataMutablePointer, count: data.count)

    //Cast to regular UnsafePointer
    let dataPointer = UnsafePointer<UInt8>(dataMutablePointer)

    //Your stream
    outputStream.write(dataPointer, maxLength: data.count)
}

defer откладывает выполнение своего блока до конца окружающего блока, поэтому dataMutablePointer.deallocate() будет выполнено после завершения outputStream.write(dataPointer, maxLength: data.count).

Но я бы написал что-то эквивалентное без копирования данных:

func sendMessage(message: String) {

    let data = message.data(using: String.Encoding.utf8, allowLossyConversion: false)!

    data.withUnsafeBytes {bytes in
        let dataPointer = bytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
        //Your stream
        outputStream.write(dataPointer, maxLength: data.count)
    }
}

Или, проще:

func sendMessage(message: String) {
    //Your stream
    outputStream.write(message, maxLength: message.utf8.count)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...