This is on XCode 6.2.
If I run the app in release mode it will crash, but with optimizations off it does not crash. The code looks straightforward. I have programmed ObjC for over a decade, so not new to programming, etc.
I note that in 32 bit it runs fine in release mode (Fastest -O), but on 64 bit real iOS hardware it crashes.
Is this a compiler bug ? Or is it possible to have poor swift that crashes only for some compiler settings (which can happen in C!).
I include code, but I'm not sure that it will help.
class func attemptLogin(completionHandler: (result: JSON?, error: NSError?) -> ()) {
// It appears that these variables are not working in the completion block in 64 with optimization on.
let email = User.email
let password = User.password
// setup login.
let parameters: [String : AnyObject] = [
"action": "login",
"login": [
"email": email,
"password": password,
"type": User.type
]
]
// Fire off REST POST Async
request(.POST, baseUrl, parameters: parameters, encoding: .JSON)
.responseSwiftyJSON { (request, response, jsonDict, error) in
// in release mode on 64 bit, things are seriously bad here.
println("jsonDict login attempt: ")
print(jsonDict)
if let token = jsonDict["login"]["token"].string {
println("token found is: " + token)
User.token = token;
User.email = email;
User.password = password;
completionHandler(result: jsonDict, error: nil)
} else {
println("No Token")
User.token = "";
User.email = "";
User.password = "";
let errorNS = NSError(domain: "stethIoUser", code: 404, userInfo: nil)
completionHandler(result: jsonDict, error: errorNS)
}
}
}
I had a similar situation yesterday.
I was running Xcode 6.2.
If I ran my app in Release mode it would crash, but with optimizations off it did not crash in Release mode. (In Debug mode it ran fine.)
The problem? This line of code:
let parts = split(columnLetters, { $0 == "," })
Yep. That was it. The split
function simply did not split my string. Instead, it assigned the entire original string to the first element of the parts array. Not surprisingly, this led to a crash later in the app.
I replaced that line of code with this, and it worked:
let parts = columnLetters.componentsSeparatedByString(",")
This bug was particularly difficult to track down for the following reasons:
The app ran fine during testing, since it was compiled in Debug mode. It took some time to eliminate other factors (iOS version, prod vs. test data) to realize that the crash only occurred in Release mode.
The app worked in Release mode if we turned off optimizations.
The crash was not related to any new code introduced since our last successful Release version that we deployed two months ago. We had been using the split
function without issue until now.
The crash did not occur on the line of code that was the problem. It occurred later in the app, as a consequence of the string not getting split.
The code compiled fine in Release mode. There was no compile error that pointed to an issue with the split
function. The function simply did not split the string.
I have not tested this on Xcode 6.3 or later. (For other reasons, we were prevented from upgrading to Xcode 6.3 / Swift 1.2, but will upgrade soon.)
I had a similar scenario. Since I believe most people coming to this question are looking more for insight on what potentially causes this, I'll share what happened with my code.
I am using ReactiveCocoa in my project, and I set up a reactive signal to be fired anytime I had a UIView
's selected stated change. It was custom view that mimics a button, but is actually derived from UIView
. In this block, I was then setting all of the other button-like views in my view to have their selected states set to NO
.
Without optimizations, this was executing fine. With optimizations, it descended into an infinite loop. Weird, eh?
In short, in my scenario, I changed this code:
[allButtons makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)];
to this
for(MyButtonLikeView* button in allButtons) {
if(button.selected) {
button.selected = NO;
}
}
I know this isn't likely going to be a solution to your problem. But I hope it's useful.
In summary, use your debugger and be on the lookout for code that is correct in Debug, but may suddenly stop working in Release.