Почему метод copy () CGImage приводит к изображению с тем же адресом памяти? - PullRequest
0 голосов
/ 26 декабря 2018

В настоящее время я борюсь с copy методом CGImage (или с тем, как CGImage работает в целом?).

Справочная информация. Я манипулировал изображением с помощью UnsafeMutablePointer и получилОшибка EXC_BAD_ACCESS.Я выяснил, что это было вызвано CGImage, уже отображенным в UIView (инкапсулированным в UIImage).Поэтому я создал копию CGImage, и она работает.Из этого я заключаю, что copy должен создать реальную копию изображения.

НО: при проверке указателей с помощью приведенного ниже кода я заметил, что адреса, на которые указывают два указателя, совпадают.

Как это может быть?

import UIKit

var uiImageIn = UIImage(named: "image2.png")!

var image1 = uiImageIn.cgImage!
var image2 = image1.copy()!

var ptr1 = UnsafeMutablePointer<UInt8>.init(mutating: CFDataGetBytePtr(image1.dataProvider!.data)!)
var ptr2 = UnsafeMutablePointer<UInt8>.init(mutating: CFDataGetBytePtr(image2.dataProvider!.data)!)

print("Image1Ptr: \(ptr1)")
print("Image2Ptr: \(ptr2) --> Same result as for ptr1!?")

Я бы ожидал, что ptr1 и ptr2 здесь будут разными.

Обновление

ОК, понял мою ошибку: В этом нет необходимостивообще создать копию CGImage, поскольку при доступе к dataProvider уже создается копия растровых данных.НО: в моем коде выше я не назначил dataProvider для какой-либо переменной.Поэтому он мгновенно освобождается, и адрес используется повторно большую часть времени (кроме того, это приводит к ошибке, если я получаю доступ к данным через один из указателей, так как dataProvider уже освобожден).

В следующем примереадреса указателей разные: импорт UIKit

var uiImageIn = UIImage(named: "image.png")!

var image1 = uiImageIn.cgImage!

var data1 = image1.dataProvider!.data
var data2 = image1.dataProvider!.data

var ptr1 = UnsafeMutablePointer<UInt8>.init(mutating: CFDataGetBytePtr(data1)!)
var ptr2 = UnsafeMutablePointer<UInt8>.init(mutating: CFDataGetBytePtr(data2)!)

print("Image1Ptr: \(ptr1)")
print("Image2Ptr: \(ptr2)")

1 Ответ

0 голосов
/ 26 декабря 2018

Ваше ожидание неверно.copy() создает поверхностную копию.Это означает, что новый объект создан, но все внутренние структуры копируются только по ссылке.Это означает, что даже если вы получите новый CGImage, поставщики данных останутся тем же объектом (и указателем).

Также обратите внимание, что с неизменяемыми объектами функция copy не обязательно должна возвращатьновый объект.Он может просто вернуть предыдущий объект (что, например, и происходит с NSArray).

Модификация data внутри провайдера случайных CGImage, вероятно, в любом случае не очень хорошая вещь, потому что выне знаю внутреннюю структуру данных (это источник данных JPEG? это источник данных PNG? это растровое изображение?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...