2014-09-29 2 views
1

Я планирую использовать переменную объекта класса для захвата введенных пользователем наборов данных в повторяющихся циклах и когда набор данных будет завершен, добавьте это в массив, содержащий все эти переменные класса. Простой пример кода в игровой площадки:Как построить массив в swift re-using переменная

class Example { 
    var a = 1 
    var b = 5 
} 

var exArray = [Example]() // this is the array holding the class variables 
var anExample = Example() // default-init the "re-usable" variable 

exArray.append(anExample) 

exArray[0].a // results in 1 as expected 
exArray[0].b // results in 5 as expected 
exArray.count // 1 as expected 

// now changing the re-usable variable properties with new user entered data 

anExample.a = 3 
anExample.b = 7 

// appending the altered variable 

exArray.append(anExample) 

exArray[0].a // shows 3 where I still expect 1 
exArray[0].b // shows 7 where I expect 7 
exArray.count // shows 2 as expected 

кажется массив содержит переменную сам (указатель?) Не копию переменной, так что постоянно меняется в пределах массива. Любые идеи о том, как я могу «перезагрузить» переменную класса без изменения члена массива?

+0

Создайте новый экземпляр примера перед установкой значения новых атрибутов. 'anExample = Example() anExample.a = 3 anExample.b = 7' – Francescu

+0

Спасибо, Франческу. Чтобы создать новый экземпляр, я должен был бы присвоить переменной другое имя, поэтому не может получить доступ к одной и той же переменной имени. Если я использую одно и то же имя, я не могу «повторить» его, поэтому изменение свойств, таких как a или b, по-прежнему будет изменять исходный объект класса anExample даже в качестве члена массива - это то, что я не хочу – swiftML

+0

You может делать то, что я вам говорил. Но если вы не хотите создавать другой экземпляр в пределах одного и того же имени переменной, как я предложил вам следует использовать Struct вместо класса. Как указано в справочной системе Swift, Struct передается через их значения, а классы передаются через их ссылки. – Francescu

ответ

2

Если вы создаете экземпляр класса и назначаете переменную, переменная содержит ссылку на экземпляр, а не сам экземпляр.

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

В зависимости от архитектуры приложения и логики вы можете захотеть превратить класс в структуру - иначе, чем класс, который является ссылочным типом, структура - тип значения, поэтому при перемещении его копия создано. Это происходит, когда:

  • присвоить переменной в другую переменную
  • вы передать его функции или метода (если не используется модификатор inout)

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

2

Если вы хотите, чтобы ваши данные копируются при присваивании, вы можете определить Example как struct вместо classSee this answer for the difference between struct and class

struct Example { 
    var a = 1 
    var b = 5 
} 

Теперь, когда вы назначаете его в массив, это добавит копию к массиву с данными в том месте, где вы его назначили.


Но если вы хотите продолжать использовать class вы должны создать новый экземпляр с данными, который вы хотите, прежде чем добавить его в массив.

+0

Большое спасибо Алекс и Антонио. Мне нужен класс для наследования, но есть варианты обхода.Попробуй со структурой вместо этого и вернешь назад, как это работает – swiftML

+0

Я пробовал вариант struct; это создает проблемы с функциями/методами в классе, поскольку методы структуры, похоже, не могут изменять собственные свойства изнутри (это код ошибки, указанный Xcode). Поэтому применил инстанцирование отдельного объекта класса для каждого элемента массива. Это действительно хорошо работает, хотя, похоже, оно не очень элегантно. еще раз спасибо за советы – swiftML

+2

Определите ваши методы struct как 'mutating func', и эти методы смогут изменять свою собственную структуру. –