2014-12-21 2 views
1

не ОК ... так что у меня не знаю, почему это происходит, но:странное поведение памяти в Swift

Сравните следующие две строки:

let pointCurve: [AnyObject] = self.curve.map{NSValue(point:$0)} 

и

let pointCurve: [NSPoint] = self.curve.map{$0} 

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

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

var pointCurve: [AnyObject] = [] 
for c in self.curve { 
    pointCurve.append(NSValue(point:NSPoint(x:1, y:1)) 
} 

против

var pointCurve: [NSPoint] = [] 
for c in self.curve { 
    pointCurve.append(NSPoint(x: 1, y: 1)) 
} 

Теперь я вижу, точно такие же результаты. Преступник, похоже, NSValue. Я проверил с Инструментами, что выделена целая группа NSConcreteValues, и я читаю онлайн, они связаны с NSValue. Но я ничего не нашел о них, вызвав утечку памяти.

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

+0

Почему вы думаете, что 'NSValue's проскальзывают? Они выделяются и сохраняются в массиве 'pointCurve'. Вы говорите, что они все еще вокруг после того, как «pointCurve» освобожден? –

+0

@GregoryHigley Ну, память неуклонно растет с размером массива. Но он должен быть освобожден в конце каждого звонка, нет? В тот момент, когда я перестаю вызывать метод (он запускается событием перемещения мыши, поэтому, когда я перестаю перемещать мышь), использование памяти перестает расти. Когда я снова начну его повторять, использование снова перерастет из того места, где оно было остановлено в предыдущее время. Ничего из этого не происходит, когда я не использую NSValue, независимо от того, вызываю ли я метод или нет, память остается стабильной. – circuitlego

+0

Попробуйте обернуть тело функции в 'autoreleasepool {}'. –

ответ

0

Try:

func pointCurvy() { 
    autoreleasepool { 
     let pointCurve: [AnyObject] = self.curve.map{NSValue(point:$0)}    
     // Do something with pointCurve. 
    } 
} 
+0

Это ... кажется, работает очень хорошо. Увеличение памяти увеличилось с ~ .3mb/sec до .1mb каждые десять секунд или около того. Я по-прежнему вижу больше использования памяти, чем без использования NSValue. Это использование, которое, похоже, не уменьшается впоследствии. Не могли бы вы объяснить, почему все лучше и почему это необходимо в проекте ARC Swift? – circuitlego

+0

Я могу только догадываться. Я не уверен, как Swift реализует массивы, но я подозреваю, что что-то вроде '[NSPoint]' довольно немного эффективнее, чем '[NSValue]'. Последнее может быть реализовано 'NSArray' под капотом, но я сильно сомневаюсь, что' [NSPoint] 'есть. –

+0

Что касается проблемы ARC, я снова могу только догадываться. Поведение, которое вы наблюдали, пахнуло объектами, добавленными в пул авторефератов, чей сток еще не был опустошен. (Возможно, потому, что вы вызываете свою функцию повторно, прежде чем попасть в нижнюю часть цикла цикла.) Что касается * почему * это происходит, я понятия не имею. –