Перед использованием переменной $result
вы должны использовать функции $row = mysql_fetch_array($result)
или mysqli_fetch_assoc()
.
Нравится это:
$row = mysql_fetch_array($result);
и использовать массив $row
как вам нужно.
Цитата из Swift Язык программирования, который отвечает на ваш вопрос:
«Компилятор Swift выполняет четыре полезные проверки безопасности, чтобы убедиться, что двухфазная инициализация завершена без ошибок:«
Проверка безопасности 1 «Назначенный инициализатор должен гарантировать, что все« свойства, введенные его классом, будут инициализированы до того, как он делегирует до инициализатора суперкласса ».
Выдержка из: Apple Inc." Быстрый язык программирования. "IBooks. https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11
blockquote>
Из docs
Проверка безопасности 1
Назначенный инициализатор должен гарантировать, что все свойства, введенные его классом, будут инициализированы до он делегирует до инициализатора суперкласса.
blockquote>
Зачем нам нужна проверка безопасности, как это?
Чтобы ответить, это позволяет перейти хотя процесс инициализации в быстрый .
Двухфазная инициализация
Инициализация класса в Swift является двухфазным процессом. На первом этапе каждому сохраненному свойству присваивается начальное значение классом, который его представил. Как только начальное состояние для каждого сохраненного свойства определено, начинается вторая фаза, и каждому классу предоставляется возможность настраивать свои сохраненные свойства еще до того, как новый экземпляр считается готовым к использованию.
Использование двухэтапный процесс инициализации делает инициализацию безопасной, но при этом дает полную гибкость каждому классу в иерархии классов. Двухфазная инициализация запрещает доступ к значениям свойств до их инициализации и не позволяет неожиданно устанавливать значения свойств на другое значение другим инициализатором.
blockquote>Итак, чтобы убедиться, что два шага процесс инициализации выполняется, как определено выше, существует четыре проверки безопасности, один из которых:
Проверка безопасности 1
Назначенный инициализатор должен гарантировать, что все введенные свойства по его классу инициализируются до того, как он делегирует до инициализатора суперкласса.
blockquote>Теперь двухфазная инициализация никогда не говорит о порядке, но эта проверка безопасности вводит
super.init
для заказа после инициализация всех свойств.
Проверка безопасности 1 может показаться неуместной, поскольку Двухфазная инициализация запрещает доступ к значениям свойств до их инициализации , без этой безопасности проверьте 1.
Как в этом примере
class Shape { var name: String var sides : Int init(sides:Int, named: String) { self.sides = sides self.name = named } } class Triangle: Shape { var hypotenuse: Int init(hypotenuse:Int) { super.init(sides: 3, named: "Triangle") self.hypotenuse = hypotenuse } }
Triangle.init
инициализируется, каждое свойство перед использованием. Поэтому проверка безопасности 1 кажется несущественной,Но тогда может быть другой сценарий, немного сложный,
class Shape { var name: String var sides : Int init(sides:Int, named: String) { self.sides = sides self.name = named printShapeDescription() } func printShapeDescription() { print("Shape Name :\(self.name)") print("Sides :\(self.sides)") } } class Triangle: Shape { var hypotenuse: Int init(hypotenuse:Int) { self.hypotenuse = hypotenuse super.init(sides: 3, named: "Triangle") } override func printShapeDescription() { super.printShapeDescription() print("Hypotenuse :\(self.hypotenuse)") } } let triangle = Triangle(hypotenuse: 12)
Выход:
Shape Name :Triangle Sides :3 Hypotenuse :12
Здесь если бы мы назовет
super.init
перед установкойhypotenuse
, то вызовsuper.init
затем вызвал быprintShapeDescription()
, и поскольку он был переопределен, он сначала вернется к реализации класса треугольникаprintShapeDescription()
.printShapeDescription()
класса Triangle получает доступ кhypotenuse
не факультативному свойству, которое еще не было инициализировано. И это недопустимо как . Двухфазная инициализация запрещает доступ к значениям свойств до их инициализации. Поэтому убедитесь, что двухфазная инициализация выполнена, как определено, необходимо, чтобы конкретный порядок вызова
super.init
, то есть после инициализации всех свойств, введенных классомself
, нам нужна проверка безопасности 1
swift принуждает вас инициализировать каждый член var до того, как он когда-либо будет использоваться. Так как он не может быть уверен, что произойдет, когда он перевернется, он ошибается: лучше безопасно, чем жаль
Swift имеет очень четкую, определенную последовательность операций, выполняемую в инициализаторах. Начнем с некоторых базовых примеров и переходим к общему случаю.
Возьмем объект A. Мы определим его следующим образом.
class A {
var x: Int
init(x: Int) {
self.x = x
}
}
Заметим, что A не имеет суперкласса, поэтому он не может вызвать функцию super.init (), поскольку он не существует.
OK, поэтому теперь давайте подкласс A с новым классом с именем B.
class B: A {
var y: Int
init(x: Int, y: Int) {
self.y = y
super.init(x: x)
}
}
Это отклонение от Objective-C, где [super init]
обычно вызывается сначала перед чем-либо еще. Не так в Свифт. Вы несете ответственность за то, чтобы ваши переменные экземпляра находились в согласованном состоянии до того, как вы сделаете что-либо еще, включая методы вызова (который включает инициализатор вашего суперкласса).
Это ошеломляюще глупый дизайн.
Рассмотрим что-то вроде этого:
.
.
.
var playerShip:PlayerShip
var deltaPoint = CGPointZero
init(size: CGSize)
{
super.init(size: size)
playerShip = PlayerShip(pos: CGPointMake(self.size.width / 2.0, 100))
playerLayerNode.addChild(playerShip)
}
.
.
.
Это неверно, как указано выше. Но так же:
.
.
.
var playerShip:PlayerShip = PlayerShip(pos: CGPointMake(self.size.width / 2.0, 100))
var deltaPoint = CGPointZero
init(size: CGSize)
{
super.init(size: size)
playerLayerNode.addChild(playerShip)
}
.
.
.
Поскольку «я» не инициализируется.
Я искренне надеюсь, что эта ошибка будет исправлена в ближайшее время.
(Да, я знаю, что я могу создать пустой объект, а затем установить размер, но это просто глупо).
Извините за уродливое форматирование. Просто поставьте символ вопроса после объявления, и все будет в порядке. Вопрос сообщает компилятору, что это значение является необязательным.
class Square: Shape {
var sideLength: Double? // <=== like this ..
init(sideLength:Double, name:String) {
super.init(name:name) // Error here
self.sideLength = sideLength
numberOfSides = 4
}
func area () -> Double {
return sideLength * sideLength
}
}
Edit1:
Существует лучший способ пропустить эту ошибку. Согласно комментарию jmaschad, нет причин использовать опциональные в вашем случае опции, которые не удобны в использовании, и вам всегда нужно проверять, не является ли опциональным нет низа, прежде чем обращаться к нему. Итак, все, что вам нужно сделать, это инициализировать член после объявления:
class Square: Shape {
var sideLength: Double=Double()
init(sideLength:Double, name:String) {
super.init(name:name)
self.sideLength = sideLength
numberOfSides = 4
}
func area () -> Double {
return sideLength * sideLength
}
}
Edit2:
После того, как два минуса вошли в этот ответ, я нашел еще лучший способ. Если вы хотите, чтобы член класса был инициализирован в вашем конструкторе, вы должны назначить ему начальное значение внутри contructor и перед вызовом super.init (). Например:
class Square: Shape {
var sideLength: Double
init(sideLength:Double, name:String) {
self.sideLength = sideLength // <= before super.init call..
super.init(name:name)
numberOfSides = 4
}
func area () -> Double {
return sideLength * sideLength
}
}
Удачи в изучении Swift.
Swift не позволит вам инициализировать суперкласс с инициализацией свойств, обратной Obj C. Таким образом, вы должны инициализировать все свойства перед вызовом super.init.
Перейдите к http://blog.scottlogic.com/2014/11/20/swift-initialisation.html . Это дает хорошее объяснение вашей проблеме.
Добавьте nil в конец объявления.
// Must be nil or swift complains
var someProtocol:SomeProtocol? = nil
// Init the view
override init(frame: CGRect)
super.init(frame: frame)
...
Это сработало для моего случая, но может не работать для ваших
«super.init ()» следует вызывать после инициализации всех ваших переменных экземпляра.
В видеоролике Apple «Intermediate Swift» (вы можете найти ее на странице видеоресурсов разработчика Apple https://developer.apple.com/videos/wwdc/2014/), примерно в 28:40, явно сказано, что все инициализаторы в суперклассе должны быть вызваны ПОСЛЕ того, как вы инициализируете переменные экземпляра.
В Objective-C это было наоборот. В Swift, поскольку все свойства должны быть инициализированы до его использования, нам нужно сначала инициализировать свойства. Это означает предотвращение вызова функции переопределения из метода «init ()» супер класса без первоначальной инициализации свойств.
Таким образом, реализация «Квадрат» должна быть:
class Square: Shape {
var sideLength: Double
init(sideLength:Double, name:String) {
self.sideLength = sideLength
numberOfSides = 4
super.init(name:name) // Correct position for "super.init()"
}
func area () -> Double {
return sideLength * sideLength
}
}
Вы просто инициируете неправильный порядок.
class Shape2 {
var numberOfSides = 0
var name: String
init(name:String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
class Square2: Shape2 {
var sideLength: Double
init(sideLength:Double, name:String) {
self.sideLength = sideLength
super.init(name:name) // It should be behind "self.sideLength = sideLength"
numberOfSides = 4
}
func area () -> Double {
return sideLength * sideLength
}
}
Edward,
Вы можете изменить код в своем примере следующим образом:
var playerShip:PlayerShip!
var deltaPoint = CGPointZero
init(size: CGSize)
{
super.init(size: size)
playerLayerNode.addChild(playerShip)
}
Это использование неявно развернутого необязательного.
В документации мы можем прочитать:
«Как и в случае с необязательными, если вы не укажете начальное значение, когда объявляете неявно разворачиваемую необязательную переменную или свойство, это значение автоматически по умолчанию равно нулю».
blockquote>