Don't mix Any and AnyObject. Currently compiler doesn't complain on mixing them but it causes this runtime error. (luckily!)
fatal error: can't unsafeBitCast between types of different sizes
Yep. This is show-stopper. If you're not sure, just use Any. Some primitive types such as Int64 doesn't support castring from AnyObject.
instance method seems to be a syntactic sugar for a free function with self binding.
If you're subclassing an Objective-C class, you must be aware of that OBJC object instance can be CHANGED
after calling super.init. So, instance variables set before calling the super.init possibly be lost after
the super.init executed if the super.init changes the instance to a new one.
class AAA: SomeOBJCClass {
var bbb = "X"
init() {
bbb = "Y"
super.init()
// What is value of `bbb` at here?
}
}
You may expect bbb to be "Y", but in practice, it possibly be "X" because OBJC runtime can replace instance object in its initialiser. If super.init replaces its instance, then bbb will stay as "X" in a new instance. Beware. This is just my guess, and not something proven.
The only way to deal with this is setting all instance variable AFTER calling super.init. Do not set any
instance variable before calling super.init. Just treat any variable set before calling super.init will be
lost.
Effectively, you need to make all object references as optional (or lazy) because it must have some initial value, and
the only value can be set at first is nil.
I am not sure that this is same on pure Swift classes. But I don't think so.
func scanLine() -> String {
struct Statics {
static let NL = UInt8(UnicodeScalar("\n"))
static var input_buffer = NSMutableData()
}
while true {
let stdin = NSFileHandle.fileHandleWithStandardInput()
let d1 = stdin.readDataOfLength(1)
let ptr1 = UnsafePointer<UInt8>(d1.bytes)
let v1 = ptr1.memory
if v1 == Statics.NL {
let s2 = NSString(data: Statics.input_buffer, encoding: NSUTF8StringEncoding)
Statics.input_buffer.length = 0
if let s3 = s2 {
return s3
} else {
fatalError("Input is not UTF8 encoded.")
}
} else {
Statics.input_buffer.appendData(d1)
}
}
}
func scanInt() -> Int {
if let i1 = scanLine().toInt() {
return i1
} else {
fatalError("The input is not a valid `Int` expression.")
}
}
func scanMultipleInts() -> [Int] {
let s = scanLine()
let ps = s.componentsSeparatedByString(" ")
let vs = ps.map { (s1:String) -> Int in
if let v1 = s1.toInt() {
return v1
} else {
fatalError("Input has one or more invalid `Int` expression.")
}
}
return vs
}
- If you make a private
@objcclass, compiler will generate a unique name for it to prevent name conflict. So private@objcclasses with same name will not conflict.
There're many reasons to cause compiler segfaults. Here're worksarounds that you can try when you see it.
- Restart Xcode.
- Erase all compilation temp directory and restart Xcode.
- See the log and duplicate the problematic file with another name and content. And erase old file. Rebuild.