Вы не можете инициализировать стандартное свойство со значением другого свойства (и нет никакого обещания, что они будут инициализированы в порядке исходного кода так, как вы предполагаете, что они будут). Вы можете инициализировать свойство lazy
со значением другого, но это слишком сложно для этой проблемы. Для доступа к свойству объекта требуется, чтобы весь объект был инициализирован, и он не инициализирован до тех пор, пока не будут установлены все свойства.
Этот вид логики лучше всего делать в init
. Вот как я бы написать его сам (с shuffle extension):
class ViewController {
//There's just one of these in the world, not one per class. And I can't
// imagine it changing (so should be let)
static let allEvents = ["SOUTHERN STATES PASS LAWS TO DISENFRANCISE BLACKS", "THEODORE ROOSEVELT ELECTED VICE PRESIDENT", "WRIGHT BROTHERS FIRST FLIGHT", "SAN FRANCISCO EARTHQUAKE", "FORD INTRODUCES MODEL T", "WORLD WAR I BEGINS IN EUROPE", "WORLD WAR I ENDS", "TR DIES – CARNEGIE DIES", "GERMAN MONEY HYPER INFLATES", "TREATY OF VERSAILLES, 19TH AMENDMENT", "HINDENBURG ELECTED PRESIDENT OF GERMANY", "STOCK MARKET CRASHES, DEPRESSION BEGINS", "HITLER’S NAZI PARTY GAINS MAJORITY IN PARLIAMENT", "HITLER BEGINS TO TAKE POWER IN GERMANY", "FRANKLIN ROOSEVELT ELECTED PRESIDENT", "FDR INAUGURATED “100 DAYS”", "HINDENBURG DIES, HITLER APPOINTS HIMSELF PRESIDENT - “ FUEHRER”", "FDR RE-ELECTED", "German airship HINDENBURG BURNS IN NEW JERSEY", "“MUNICH” – British P.M. Chamberlain agrees that Hitler can have Czechoslovakia.", "Germany invades Holland, Belgium and France – Churchill becomes P.M.", "Germany invades Russia", "JAPANESE ATTACK PEARL HARBOR – U.S. DECLARES WAR ON JAPAN", "HITLER DECLARES WAR ON U.S."]
// Do you really need both of these? If so, I'd probably actually just keep
// eventIndices and compute events when needed, but if you access it a lot,
// this is fine. But "event1" "event2" etc is bad practice
let eventIndices: [Int]
let events: [String]
init() {
eventIndices = Array(ViewController.allEvents.indices.shuffled().prefix(4))
events = eventIndices.map { ViewController.allEvents[$0] }
}
}
ОК, вот как я бы это сделать, но если мы хотим, чтобы держать его в стиле у вас есть, мы все еще можем сделать это. Вам все равно понадобится allEvents
, чтобы быть static
.
class ViewController {
static let allEvents: [String] = ["SOUTHERN STATES PASS LAWS TO DISENFRANCISE BLACKS", "THEODORE ROOSEVELT ELECTED VICE PRESIDENT", "WRIGHT BROTHERS FIRST FLIGHT", "SAN FRANCISCO EARTHQUAKE", "FORD INTRODUCES MODEL T", "WORLD WAR I BEGINS IN EUROPE", "WORLD WAR I ENDS", "TR DIES – CARNEGIE DIES", "GERMAN MONEY HYPER INFLATES", "TREATY OF VERSAILLES, 19TH AMENDMENT", "HINDENBURG ELECTED PRESIDENT OF GERMANY", "STOCK MARKET CRASHES, DEPRESSION BEGINS", "HITLER’S NAZI PARTY GAINS MAJORITY IN PARLIAMENT", "HITLER BEGINS TO TAKE POWER IN GERMANY", "FRANKLIN ROOSEVELT ELECTED PRESIDENT", "FDR INAUGURATED “100 DAYS”", "HINDENBURG DIES, HITLER APPOINTS HIMSELF PRESIDENT - “ FUEHRER”", "FDR RE-ELECTED", "German airship HINDENBURG BURNS IN NEW JERSEY", "“MUNICH” – British P.M. Chamberlain agrees that Hitler can have Czechoslovakia.", "Germany invades Holland, Belgium and France – Churchill becomes P.M.", "Germany invades Russia", "JAPANESE ATTACK PEARL HARBOR – U.S. DECLARES WAR ON JAPAN", "HITLER DECLARES WAR ON U.S."]
static func generateRandomIndex() -> [Int] {
var eventIndex1: Int = 0
var eventIndex2: Int = 0
var eventIndex3: Int = 0
var eventIndex4: Int = 0
while (eventIndex1 == eventIndex2) || (eventIndex2 == eventIndex3) || (eventIndex1 == eventIndex3) || (eventIndex1 == eventIndex4) || (eventIndex2 == eventIndex4) || (eventIndex3 == eventIndex4) {
eventIndex1 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count)
eventIndex2 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count)
eventIndex3 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count)
eventIndex4 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count)
}
return [eventIndex1, eventIndex2, eventIndex3, eventIndex4]
}
let index1: Int
let index2: Int
let index3: Int
let index4: Int
let event1: String
let event2: String
let event3: String
let event4: String
init() {
let eventIndexes = ViewController.generateRandomIndex()
index1 = eventIndexes[0]
index2 = eventIndexes[1]
index3 = eventIndexes[2]
index4 = eventIndexes[3]
event1 = ViewController.allEvents[index1]
event2 = ViewController.allEvents[index2]
event3 = ViewController.allEvents[index3]
event4 = ViewController.allEvents[index4]
}
}
Если allEvents
не нужно увидеть за пределами этого файла, вы можете сделать его более простым поднятием его в файл объем:
fileprivate let allEvents: [String] = ["SOUTHERN STATES PASS LAWS TO DISENFRANCISE BLACKS", "THEODORE ROOSEVELT ELECTED VICE PRESIDENT", "WRIGHT BROTHERS FIRST FLIGHT", "SAN FRANCISCO EARTHQUAKE", "FORD INTRODUCES MODEL T", "WORLD WAR I BEGINS IN EUROPE", "WORLD WAR I ENDS", "TR DIES – CARNEGIE DIES", "GERMAN MONEY HYPER INFLATES", "TREATY OF VERSAILLES, 19TH AMENDMENT", "HINDENBURG ELECTED PRESIDENT OF GERMANY", "STOCK MARKET CRASHES, DEPRESSION BEGINS", "HITLER’S NAZI PARTY GAINS MAJORITY IN PARLIAMENT", "HITLER BEGINS TO TAKE POWER IN GERMANY", "FRANKLIN ROOSEVELT ELECTED PRESIDENT", "FDR INAUGURATED “100 DAYS”", "HINDENBURG DIES, HITLER APPOINTS HIMSELF PRESIDENT - “ FUEHRER”", "FDR RE-ELECTED", "German airship HINDENBURG BURNS IN NEW JERSEY", "“MUNICH” – British P.M. Chamberlain agrees that Hitler can have Czechoslovakia.", "Germany invades Holland, Belgium and France – Churchill becomes P.M.", "Germany invades Russia", "JAPANESE ATTACK PEARL HARBOR – U.S. DECLARES WAR ON JAPAN", "HITLER DECLARES WAR ON U.S."]
class ViewController {
...
event1 = allEvents[index1]
event2 = allEvents[index2]
event3 = allEvents[index3]
event4 = allEvents[index4]
...
Но главный урок во всем этом является то, что вы можете 'Свойства доступа в объекте до инициализации объекта.
Функция 'generateRandomIndex()' не делает то, что вы думаете. Он не обещает отсутствие дубликатов (вы использовали '&&', когда вы имели в виду '||'). Стандартный способ делать то, что вы пытаетесь сделать, называется перетасовкой. См. Http://stackoverflow.com/questions/24026510/how-do-i-shuffle-an-array-in-swift –
Ваше утверждение «глобальный охват» смутило Эрика (вы не имели в виду «глобальный охват», вы имели в виду что это свойства ViewController). –
@RobNapier, я немного новичок в коде, поэтому я не совсем понимаю синтаксис, используемый для создания метода тасования. Было бы намного проще, если бы я мог использовать более простой синтаксис для передачи моей логики. Итак, что случилось с использованием &&? Цикл while продолжает генерировать случайные числа, пока ВСЕ (следовательно, &&) индексы событий не будут идентичны друг другу. Используя || разрушит эту логику. –