I cannot build my project due to an error(Segmentation Fault 11). With commenting things out, I found that the error is thrown by this line:
typealias functionType = ([Expression], [String: NSNumber], inout AnyObject) -> Expression!;
If I remove the typealias and use the raw type instead, the error gets still thrown, so the mistake is probably not the typealias, but the closure.
Edit:
If I replace the type Expression with AnyObject the error gets still thrown. But if I just declare the typealias, I can use it for a global variable but not for a member variable.
I also got this error (following an online tutorial), I removed all the code I entered before to get this error and the problem persist, it seems to me as the project was corrupted. I'm not an expert so please take this report with caution.
This is happened just after appeared an error HUD telling sourceKitService Crashed...
The probably offending code was this one:
override func viewWillAppear(animated: Bool) {
if var storedtoDoItems: AnyObject! = NSUserDefaults.standardUserDefaults().objectForKey("toDoItems") {
toDoItems = []
for var i = 0; i < storedtoDoItems.count; ++i {
toDoItems.append(storedtoDoItems[i] as NSString)
}
println(storedtoDoItems)
}
taskTable.reloadData()
}
Related
I'm relatively new to Swift, so I hope I'm not asking a stupid question.
I have some code that instantiates an array of type Error, which will later be iterated and printed to the console. When running this code through Instruments using the "Leaks" instrument, it shows a leak of _SwiftNativeNSError. If I change the array type from [Error] to [Any], the leak disappears, even though it is still actually holding an object conforming to Error. The leak is not reproducible with any other data types or protocols that I've tried.
Here's some sample code:
class myLeak {
lazy var errors = [Error]()
enum err: Error {
case myFirstError
}
func doSomething() {
errors.append(err.myFirstError)
for error in errors {
print(String(describing: error))
}
}
}
// call with let myleak = myLeak(); myleak.doSomething()
Calling the doSomething() function immediately creates a leak. Switching [Error]() to [Any]() resolves the leak, but I'm not happy with this as a solution without understanding the underlying problem. The problem is also solved by changing [Error]() to my enum implementing the Error protocol: [err](). I've also tried creating my own custom protocol just to prove if this is being caused specifically by Error, and I'm only able to reproduce the problem when using Error; my own custom protocol did not exhibit this behaviour.
Originally, my code used a forEach loop to iterate the array, but I then tried re-writing it to use a standard for loop in case the closure in forEach was causing the issue, but this didn't work.
I'm suspicious that this may be a Swift bug (in which case, I will open an issue for it), but there's also a chance that I'm missing a key piece of understanding. If what I'm doing is bad practice, I'd like to understand why.
Update:
After speaking with Joe Groff, an Apple engineer, this is the bug you could have encountered: https://bugs.swift.org/browse/SR-6536
Original Answer
I've played a bit with your code and I think the problem is due to Error type.
In fact, taking the code by Josh, you can find a different behaviour if you use Error or MyError as the type of your array.
I guess the problem arises since the deinit call is not forwarded to CustomObject since Error is just a protocol and it's not aware of the underlying class. While, MyError is. We can wait for other people to have clarifications on this behaviour.
Just for simplicity, I'm using a Playground here. See that I'm not even trying to print the error value.
import UIKit
class ViewController: UIViewController {
var errors: [Error] = [] // change to MyError to see it working
enum MyError: Error {
case test (CustomObject)
}
class CustomObject {
deinit {
print("deiniting")
}
}
override func viewDidLoad() {
super.viewDidLoad()
let testerror = MyError.test(CustomObject())
errors.append(testerror)
errors.removeAll()
}
}
do {
let viewController = ViewController()
// just for test purposes ;)
viewController.viewDidLoad()
}
I tested your code and it looks like the String(describing) statement is causing the string to retain the error, which is just weird. Here is how I can tell: I created an associated object that prints out when its being deinitialized.
import UIKit
class ViewController: UIViewController {
var errors = [Error]()
override func viewDidLoad() {
super.viewDidLoad()
class CustomObject {
deinit {
print("deiniting")
}
}
enum MyError: Error {
case test (CustomObject)
}
let testerror = MyError.test(CustomObject())
errors.append(testerror)
for error in errors {
//print(String(describing: error))
}
errors.removeAll()
}
}
When the print doesn't run, sure enought he associated object is deinitialized at when the error is removed from the array and the output is:
deiniting
Uncomment the print and the output becomes:
test(CustomObject #1 in stack.ViewController.viewDidLoad() -> ())
At first I thought it was the print that's the problem but If I refactor to:
errors.forEach{print($0)}
I get the output:
test(CustomObject #1 in stack.ViewController.viewDidLoad() -> ())
deiniting
But if I change it to:
errors.map {String(describing:$0)}.forEach{print($0)}
Then deinit is no longer called:
test(CustomObject #1 in stack.ViewController.viewDidLoad() -> ())
Weirdness. Maybe file a radar?
This bug was Fixed in Xcode 9.3.
We have an app with a fairly broad Core Data model, with lots of custom subclasses implemented in Objective C, but which are also used by a growing fraction of the app that's written in Swift. (For what it's worth: we're building with Xcode 7.3.1 against iOS 9.3, and the Swift code is thus 2.2.)
There's a helper function written in Swift that looks like this:
extension NSManagedObject {
func inContext<T: NSManagedObject>(moc: NSManagedObjectContext) -> T? {
guard self.managedObjectContext != moc else {
return (self as! T)
}
do {
let obj = try moc.existingObjectWithID(self.objectID)
return (obj as! T) // <--- fails here
}
catch let error {
return nil
}
}
}
This is called in a fair number of places where objects jump contexts. Calling code generally looks like this:
let result: ECFoo? = foo.inContext(managedObjectContext)
This works flawlessly in debug builds of the app. But with optimizations turned on, I'm running into a case where this call fails at the line I've marked, where the fetched object is being cast from NSManagedObject to the correct subclass. The stack trace starts with swift_dynamicCastObjCClassUnconditional, and the message that gets logged to the console is:
Could not cast value of type 'ECFoo_Foo_' (0x7fb857d2c250) to 'ECFoo_Foo_' (0x7fb857d2c250).
If I put a breakpoint on that line, what I'm attempting to do seems fine in the debugger console:
(lldb) po moc.existingObjectWithID(self.objectID) is ECFoo
true
This is deeply confusing, because it's clearly the same type on both sides here, and they both appear to be the dynamically generated subclass, rather than the formal class that it should be trying to cast to (based on inference of the calling code). I can only assume that there's some piece of information being optimized away that is necessary to make this work, but I'm not entirely sure how to fix it.
I want to make a Tetris Game Project in iOS. But I am facing this problem in this picture. The Xcode occur this ERROR, I couldn't fix it. I used to think, a Shape class has 7 of different Shape subclasses and I divided them in 8 files included the Shape class, that may occur this ERROR. Then I put all of them in one file. However, It occur again.
Here is some of my codes:
class Shape: Hashable, CustomStringConvertible{
let color: BlockColor
var blocks = Array<Block>()
var orientation: Orientation
var column: Int = 0
var row: Int = 0
// 每个块中的每个小块的位置
var blockColRowPositions: [Orientation: Array<(col: Int, row: Int)>]{
return [:]
}
// 每个块在底部的形状
var bottomBlocksForOrientations: [Orientation: Array<Block>]{
return [:]
}
var bottomBlock: Array<Block>{
guard let bottomBlocks = bottomBlocksForOrientations[orientation] else{
return []
}
return bottomBlocks
}
var hashValue:Int{
return blocks.reduce(0) {$0.hashValue ^ $1.hashValue}
}
var description:String{
return "\(color) block facing \(orientation) : \(blocks[firstIndex]), \(blocks[secondIndex]), \(blocks[thirdIndex]), \(blocks[forthIndex])"
}
// ....
}
class O_Shape: Shape {
// 每个块中的每个小块的位置
override var blockColRowPositions: [Orientation: Array<(column: Int, row: Int)>] {
return [
Orientation.zero: [(0,0),(1,0),(0,1),(1,1)],
Orientation.twoQuater: [(0,0),(1,0),(0,1),(1,1)],
Orientation.fourQuater: [(0,0),(1,0),(0,1),(1,1)],
Orientation.sixQuater: [(0,0),(1,0),(0,1),(1,1)]
]
}
override var bottomBlocksForOrientations: [Orientation: Array<Block>] {
return[
Orientation.zero: [blocks[thirdIndex], blocks[forthIndex]],
Orientation.twoQuater: [blocks[thirdIndex], blocks[forthIndex]],
Orientation.fourQuater: [blocks[thirdIndex], blocks[forthIndex]],
Orientation.sixQuater: [blocks[thirdIndex], blocks[forthIndex]]
]
}
}
The picture suggests it is crashing during the compilation. This used to be a fairly common occurrence with Swift but is less so now.
The first thing you should o is make sure you are on the latest version of Xcode, which is 7.2.1.
If the compilation crash is still happening, you might be able to fix the problem by finding out which line of code causes the crash. I used to do this by commenting out the whole file and then uncommenting bits one by one until it causes the crash.
Then you need to find a way of rewriting the code so as to avoid the crash and you also need to send a bug report to Apple # https://bugreport.apple.com. It doesn't matter what code you throw at it, the compiler should not crash, if your code is wrong, it should produce an error message.
I have two properties. One of them is optional. these are defined below:
var advertiseCompleteBlock: (() -> ())!
var isAdvertiser: Bool = false;
Now, if I try to use this in my code like below, the compiler throws an error while building and fails with error code 254.
if (self.isAdvertiser && self.advertiseCompleteBlock) {
self.advertiseCompleteBlock();
}
But if I change it like below, it works fine:
if (self.isAdvertiser && self.advertiseCompleteBlock) {
if (self.advertiseCompleteBlock) {
self.advertiseCompleteBlock();
}
}
Can anyone explain how are these two blocks of code different and what am I doing wrong here?
If advertiseCompleteBlock is really optional it should probably be declared with a ? instead of ! which says that it will always exist.
I put your original code in a test file as a simple func and removed the references to self and it compiled fine. I don't know what the error 254 would be.
Is this code really what you want?
var advertiseCompleteBlock: (() -> ())? --> really optional
var isAdvertiser: Bool = false;
if (isAdvertiser && advertiseCompleteBlock) {
advertiseCompleteBlock!(); --> but now guaranteed
}
Your block var is optional and is not initialized. So while unwrapping it will definitely be nil which compiler does not expect. That's the reason you get the compile errors.
In the second case you are checking if the var is nil or not and then calling the block, so the compiler is happy in this case.
I Wrote a function that return two Strings, when calling the function regularly its works fine, but when I'm running the function through loop, I'm getting this error:
Thread 1: EXC_BAD_ACCESS (code=2, address=0xbfffcba0)
override func viewDidLoad()
{
super.viewDidLoad()
test()
}
func test()
{
var funcs = [checkButton]
var a = checkButton(value: 1) // Runs OK
for f in funcs{
var result = f(value: 1) // Fail
}
}
func checkButton(#value: Int) -> (location: String, pattern: String){
return ("abc","cba")
}
Update:
I'm using Xcode 6 beta 2, and running Mavericks on VMware Workstation.
Also, I've just created new clean project with that code and still getting the error.
This code runs fine for me. Your EXC_BAD_ACCESS must be coming from some other part of your code. Try setting a breakpoint and stepping through the code to find the line throwing the error.
From the “The Swift Programming Language.”
“An instance method can be called only on a specific instance of the type it belongs to. It cannot be called in isolation without an existing instance.”
checkButton() is an instance method, not a closure. It works in the first case because there is an implicit self. before checkButton(). It will not work in the second case.
If you want to make checkButton a closure you could declare it like so:
let checkButton = { (#value: Int) -> (location: String, pattern: String) in
return ("abc","cba")
}
I can confirm that it doesn't work for me either. Created a iOS single-view app from template, and added above code. crash. As an experiment, I took it out of the array (just f = self.checkButton) and got the same result.
I think it's a bug in the compiler.
First according to the book, a method is actually a function which is actually a closure, albeit one with special properties and restrictions. Shouldn't self.checkButton (or implicit version) be sufficient to "give it an existing instance", making it a closure? If MattL is correct that instance methods can't be used as closures, then the compiler shouldn't allow you to assign one to anything.
Second, the crash occurs on the exit, not on the call. And if you reference self in checkButton, (e.g. println(self.title) having previously set title), it works fine. That suggests that the instance is indeed known and operating, just something wrong on the return.
Third, changing it to a class method doesn't help. Changing these lines
var a = ViewController.checkButton(value: 1)
var funcs = [ViewController.checkButton]
class func checkButton(#value: Int) -> (location: String, pattern: String)
results in the same crash. I don't see any similar prohibition on context for class methods.
Fourth, if you simply change the return type from (location: String, pattern: String) to just String and return abc, then the whole thing works fine.
Fourth, if you wrap test and checkButton in a new class testClass, and then call it as below, it works:
class testClass {
func test()
{
var funcs = [checkButton]
var a = checkButton(value: 1) // Runs OK
for f in funcs {
var result = f(value: 1) // Fail
println(result)
}
}
func checkButton(#value: Int) -> (location: String, pattern: String){
return ("abc","cba")
}
}
class ViewController: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
let g = testClass()
g.test()
}
}
Now change testClass to testClass: NSObject and it crashes.
So it looks like the compiler is botching up a method return when called as a closure with a tuple in a Obj-C subclass. When I put it like that, I must say that it's not terribly surprising nobody's noticed yet; you're really pushing the edge here!
More practically, in the meantime, if it's helpful, an alternative to changing your method to a closure is to keep it unchanged and just wrap it as you put it in the array:
var funcs = [{value in self.checkButton(value: value)}]
This seems to work.