Skip to content

Instantly share code, notes, and snippets.

@eonil
Last active July 24, 2016 09:42
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eonil/07b82b102a4e72f4d85f to your computer and use it in GitHub Desktop.
Save eonil/07b82b102a4e72f4d85f to your computer and use it in GitHub Desktop.
Swift Note

Swift Note

Swift Note #1

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.

Swift Note #2

instance method seems to be a syntactic sugar for a free function with self binding.

OBJC Subclasses and Init

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.

Reading by Line from STDIN

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
}

OBJC Related Stuffs

  • If you make a private @objc class, compiler will generate a unique name for it to prevent name conflict. So private @objc classes with same name will not conflict.

Compiler Segfault

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment