Command failed due to signal: Segmentation fault: 11 when Compiling Swift Project - ios

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.

Related

Swift memory leak when iterating array of Errors

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.

What is the cause of EXC_BAD_ACCESS crashes for classes declared in separate files?

I have come across this problem several times now, without ever finding the cause.
When attempting to access a property of ClassY in ClassX I get an EXC_BAD_ACCESS error. This happens even if I instantiate a clean copy and attempt to access the property immediately:
let classY = ClassY()
println(classY.someTextProperty)
EXC_BAD_ACCESS
As far as I am aware this error should only be caused by trying to access a deallocated instance, which presumably cannot be the case in the above code.
Where it gets strange, is that if I declare ClassY in the same file as ClassX then the problem disappears. (ClassY does have some private properties, but I am not trying to access these and anyway, making them all public does not solve the problem)
I am not including the source code here since there is more of it than is practical to isolate. I have not been able to reproduce this reliably in a standalone project because I am unable to find any kind of pattern.
Has anyone come across a similar kind of problem, and does anyone have an idea for a solution (obviously I can include the definition in the same file, but that is a workaround rather than a solution)?
I am currently running iOS 8.3 / Swift 1.2 but had this problem already in iOS 8.1.
UPDATE
Following lots of trial and error, it seems that the problem comes from lazy properties and protocol conformance. Again this is not something I can reproduce in a plain playground (perhaps the declarations need to be in different files).
My ClassY conforms to ProtocolY which has several properties:
protocol ProtocolY {
var number: Int { get }
var text: String { get }
}
When ClassY conforms to ProtocolY, if it implements either of the properties as a lazy property then accessing a property causes the EXC_BAD_ACCESS crash. If ClassY is not marked as conforming to ProtocolY or if none of the properties declared in ProtocolY as implemented by ClassY are lazy properties then no crash occurs.
Obviously this is just narrowing down but still does not give me an explanation. I know of no reason why implementations of protocol properties should not be lazy.
UPDATE Here is an example of properties on ClassY:
private(set) lazy var currentPage: Int = {
let subject: RACReplaySubject = RACReplaySubject(capacity: 1)
subject.sendNext(self.currentPage)
return subject
}()
var currentPage: Int {
didSet {
(self.currentPageSignal as? RACSubject)?.sendNext(self.currentPage)
}
}
currentPage is set in the init method.
If I use instead:
private(set) var currentPage: Int = {
let subject: RACReplaySubject = RACReplaySubject(capacity: 1)
return subject
}()
var currentPage: Int {
didSet {
(self.currentPageSignal as? RACSubject)?.sendNext(self.currentPage)
}
}
(and do a sendNext in the init method) then everything works fine.
I'm fairly confident that the fact that I'm using ReactiveCocoa is irrelevant - I have also tried lazy properties which are simple Strings, with the same result.

EXC_ARM_DA_ALIGN when reading from NSData in Swift

I have the following class:
class RawDataArray {
var data: NSData!
init(filePath: String) {
data = NSData(contentsOfFile: filePath)
}
func read<T>(offset: Int) -> T {
return UnsafePointer<T>(data.bytes + offset).memory
}
}
which I use in my iOS app to read from a binary file with a custom format. For example, to read an Int at offset 5, I use:
let foo = rawData.read(5) as Int
This works in the simulator, on my iPad Air, and has passed the review for beta testing. However, my external testers have iPad 2s and 4s, and they are getting EXC_ARM_DA_ALIGN errors.
I cannot change the structure of the input file. Is there any way to fix the read function to make sure the objects are built from properly aligned memory locations?
Yes, reading unaligned data can fail on some architectures.
A safe method is to copy the bytes into a (properly aligned) variable.
So the first idea would be to write a generic function:
func read<T>(offset: Int) -> T {
var value : T
memcpy(&value, data.bytes + offset, UInt(sizeof(T)))
return value
}
However, this does not compile, because the variable value
must be initialized before being used, and there is no default
constructor that can be used to initialize a complete generic
variable.
If we restrict the method to types which can be initialized with 0 then we get this:
func read<T : IntegerLiteralConvertible>(offset: Int) -> T {
var value : T = 0
memcpy(&value, data.bytes + offset, UInt(sizeof(T)))
return value
}
This works for all integer and floating point types.
For the general case, one could use the idea from https://stackoverflow.com/a/24335355/1187415:
func read<T>(offset: Int) -> T {
// Allocate space:
let ptr = UnsafeMutablePointer<T>.alloc(1)
// Copy data:
memcpy(ptr, data.bytes + offset, UInt(sizeof(T)))
// Retrieve the value as a new variable:
var item = ptr.move()
// Free the allocated space
ptr.dealloc(1)
return item
}
Swift allows to overload functions with different return types,
therefore you can actually define both methods, and the compiler will
automatically choose the more restrictive one.
FOR ALL SWIFT DEVELOPERS THAT READ THIS
I had a different case with the same crash type!
If your project is defined for (old?) swift version, but you link against a cocoa pod (in my case) that has a different (newer?) swift version in build settings - you’re going to get that crash even when you just trying to set a value of a public field in a regular swift struct.
The stack trace will tell you nothing and may show you the wrong place (CAAnimation free memory for example)
In my case my project was in Swift 4, and my pod (SwiftMessages) was Swift 4.2
AND BOOM!!!
Happy coding!

Xcode 6.0.1 Segmentation Fault 11

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()
}

Swift function that return two strings fail when its in loop

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.

Resources