2017-02-09 15 views
1

Следующий код:Почему этот код падает на iPhone 5?

func getCurrentMillis() -> Int64 { 
    return Int64(Date().timeIntervalSince1970 * 1000) 
} 

падает на [32 бит] iPhone 5 с сообщением:

EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xe7ffdefe) 

Я не понимаю, почему кажется, что результат этого вычисления должны вписываться в Int64, или я Я чего-то не хватает?

StackTrace показывает это (TextProcessor.textDidChange() звонки getCurrentMillis()):

enter image description here

запрос Per OOPer, я добавить соответствующий код TextProcessor:

var timeOfLastInput: Int64 = 0 

... 

if getCurrentMillis() - timeOfLastInput > 150 { 
    textMap.cursorPosition = nil 
} 

Update: I» отправил отчет об ошибке Apple.

+0

Если вы знаете, что 'Int64' доступен на 32-разрядных устройствах, почему бы вам не показать код' TextProcessor.textDidChange() '. Я могу заверить, что ваш 'getCurrentMillis()' отлично работает на 32-битных устройствах. Проблема заключается в стороне вызывающего абонента. – OOPer

+0

'Int64' * * доступен в 32-битных системах. Проблема должна быть где-то в другом месте. –

+0

Вы уверены, что авария находится в функции getCurrentMillis? Я не вижу этого из backtrace стека. –

ответ

3

Я не уверен, что происходит в Swift компилятором, но когда вы пишете:

if getCurrentMillis() - timeOfLastInput > 150 { 

Swift использует этот в многочисленных перегруженных операторов вычитания:

public func -<T : Strideable>(lhs: T, rhs: T) -> T.Stride 

(Протестировано с Xcode 8.2.1.)

К сожалению, Int64.Stride - Int, поэтому результат операции переполняется, когда timeOfLastInput составляет 0 в 32-разрядных системах.

Чтобы обойти это поведение Swift, вы можете изменить линию:

if getCurrentMillis() > timeOfLastInput + 150 { 

Во всяком случае, вы бы лучше отправить bug report to Apple или to swift.org.

+1

Хорошая добыча! Аналогичная проблема наблюдалась здесь: http://stackoverflow.com/questions/27496415/swift-type-conversions. –

+1

Я предполагаю, что 'if getCurrentMillis() - timeOfLastInput> Int64 (150)' будет работать. - Но в любом случае это поведение не является интуитивным и противоречит заявленной «безопасности» Свифта. –

+0

Мне любопытно, где указано, что 'Int64.Stride' является' Int'? –

-2

Как вы уже знаете, ваш iphone 5 работает на 32-битной системе. Вы хотите использовать Int кодировку на 64 бита. На самом деле, это не может совпадать. Ваш iphone не может его сохранить.

Чтобы расширить решение the_dahiya_boy: размер Int совпадает с Int32 в 32-битной системе и имеет тот же размер, что и Int64 на 64-битной системе.

Reference