All posts by admin

Map, FlatMap in swift

ref – http://sketchytech.blogspot.com.by/2015/06/swift-what-do-map-and-flatmap-really-do.html
https://chrisbrandow.svbtle.com/swift-map-vs-flatmap

Map

Operate on the contents of the array. Maps unwraps a container ( array, dictionary…etc) , transforms value with supplied function and rewraps result.

output of each element:
1
2
3
4
5
6

Let’s apply adding 2 to each element

3
4
5
6
7
8

Let’s return it as an array

[3, 4, 5, 6, 7, 8]

In this example, for each element in the array, let’s add 2.
So if you use print($0), you can see that each element is an integer.
And thus, we are able to add 2 to it.

Flat Map

flatMap unwraps a container (array, dictionary…etc), transforms value with supplied function and rewraps either a raw value, or the non-nil value of a contained result.

nil values are thrown out.

Flattening bottom most array

FlatMap doesn’t operate on the contents of the array, it operates on the array itself.

If you flatten an normal array, it defaults down to the element because we’r “pushing down”. If the bottom most array gets pushed down, they become elements.
If an array of an array gets pushed down, it simply goes down one level.

In our case, $0. would then get the properties of the integer type. This shows that the bottom most array gets flattened to elements.

Flattening arrays

If we have an array within an array, it would flatten everything, and get it as an array. In this case $0 is an array, and thus,
we can use property count. As mentioned previously, this array is not the bottom most array, and we simply push the array down one level to
[1, 2, 3, 4, 5, 6]

we apply $0.count to the array, and get 6 back. 6 is stored in an array, which is then returned back to us

What about array of array of array?

It becomes [[1, 2, 3, 4, 5, 6]]

array of array of array of array?

[[[1, 2, 3, 4, 5, 6]]]

Pretty straightforward.

Applying flatMap to bottom most array turns the array into individual elements.
Applying flatMap to array in an array, simply brings it down one level.

Let’s see an combination in action. Here, we see 2 arrays inside an array. They are not bottom most array and
hence are simply flattened down 1 step:

element is [1, 2, 3, 4, 5, 6]
element is [7, 8, 9]

$0.count would bring us 6 from the 1st element (which is an array of 6 ints)
and 3 from the 2nd element (which is an array of 3 ints)
it then returns us the array with the results: [6,3]

Double FlatMap

Now, let’s add an array in the 2nd array.
When we do a flat map, we get something like this:

element is [1, 2, 3, 4, 5, 6]
element is [7, 8, 9, [10, 11, 12]]

Let’s see what happens if we flatten it again!

Hence when applying our rules mentioned above,
when flatMap gets applied a 2nd time to
[1, 2, 3, 4, 5, 6], it becomes:

1
2
3
4
5
6

because its a bottom most array.

for [7, 8, 9, [10, 11, 12]], it becomes:

7
8
9
[10, 11, 12]

flatMap nil array

So the idea is, map rewraps the results inside of the array, resulting in an array of contained strings and nils.
flatMap places only the non-nil contained value into the array, resulting in an array of data ONLY.

Let’s take a look at flatMap first:

If you were to process flatMap, you have a base array of nils. You flatten it, you get 3 element of nils.
You would then return nil for all the elements, the resulting array will be empty.

Thus, you’ll get an empty array if you have an
array of nil calling flatMap.

output:
[]

map nil array

The flatMap is pretty much the same as map, except that the return value of the closure in map is not allowed to return nil, while the closure of map can return nil.

Now let’s see what happens if we use map.

We create an array of optional Strings. There is a separator element there in which we give it nil

Hence at this point it is, [nil]

When we map and print the element, we see that its nil

Thus, we return nil to the array creation. The difference is that if we return nil to the array under map, due to the definition
of map (which is apply so and so to the element), we basically apply NOTHING to the nils, then return them back to the array creation.
that is why we still see the nil.

output:

[nil]

C function pointers are imported into Swift as closures

https://stackoverflow.com/questions/24330263/lifetime-of-retained-memory-in-swift-closures
https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html#//apple_ref/doc/uid/TP40014216-CH8-XID_13

One generally does not need to worry about how __block variables work internally.

But basically, the variable is wrapped in a simplified “object” kind of thing, with the actual “variable” being a field of this “object”, which is memory-managed through reference counting.

Blocks that capture them hold “strong references” to this pseudo-object thing — when a block is created on the heap (technically, when they are copied from stack blocks to the heap) that uses this __block variable, it increases the reference count; when a block that uses it is deallocated, it decreases the reference count. When the reference count goes to 0, this pseudo-“object” is deallocated, invoking the appropriate destructor for its variable type first.

Retain Cycle in Swift 3 using ViewController and Singleton

demo

Using Strong

singleton_strong_viewcontroller

If your singleton’s block code strongs the viewcontroller, it will keep the ViewController around.

1) Your singletons starts processing data
2) You exit (cancel/pop) your ViewController. At this point ViewController will not dealloc because the block of your Singleton has stronged ViewController
3) Your function finishes processing
4) Then it executes its callback (block code). It goes through the print statements, then uses the strong self, and calls ViewControler’s random(). When all of that is done. The code block is finished. The local stack is popped, including the self reference. Thus, this nils the strong to the ViewController.

5) In Swift, it still remembers that the user wanted to cancel the ViewController. Thus, when it notices that is it not stronged by the block’s self anymore, it goes ahead and deallocates. Thus, avoiding floating around uncollected in memory.

In objective-C, it does not remember that the user wants to dealloc the ViewController. Since it is stronged by the block’s self, it won’t call dealloc. When the block is done and pops its local stack the and strong self reference, the ViewController is still there. It does not remember that the user wants to exist and thus, does not re-evaluate its strong reference count. Therefore, your ViewController becomes an uncollected object in memory. Thus, the way it works in Swift is an improvement over Objective C.

After our singleton finishes processing all that data, it runs through the block code, sends whatever message it needs to the strong self. At the end of the code block, the local stack pops, thus removing the strong to the ViewController. The ViewController will only dealloc/deinit itself when it sees that there is no strong reference to it. That’s why in the log, you’ll see all the processing and block code print logs, and then execution hits the ViewController’s dealloc/deinit.

strong_swift_remembers_your_pop

You will see that the block code successfully uses the strong self to send a message to ViewController’s function and displays log. This is because ViewController is still around. If we are to use weak, ViewController will not be around, and you won’t be able to log, as you will see from the weak example below.

strong_block_viewcontroller_valid

Using weak

singleon_weak_viewcontroller

MySingleton’s block has a weak pointing to the ViewController. When that ViewController get popped, it will see that it DOES NOT have any strong references to it, thus calling its de-init function:

weak_block_viewcontroller_deinit

NOTICE HERE that even though the singleton function is still processing data, ViewController went ahead and de-inited in the middle of the process.
This is because ViewController has no other strong references pointing to it.

Now, what happens when Data finishes processing and the callback access the deallocated ViewController’s function?

When MySingleton.shared.processSomeBigDataThatTakesLongTime finishes, it will process its callback and execute the block below:

Notice it calls ViewController’s random function. However, ViewController has already been deallocated and its memory address has junk. Thus, the weakSelf reference will nil itself (A weak reference will automatically get nil when its referenced object is deallocated). Thus, nothing happens when we try to dereference it and call random().

weak_block_viewcontroller_not_there_anymore

As you can see, calling random() does nothing because ViewController object is not there to process it.

Array with nils (swift)

Non nil Arrays

array_nil_1

Array OF optionals

http://stackoverflow.com/questions/25589605/swift-shortcut-unwrapping-of-array-of-optionals

Notice ‘?’ is inside of the bracket, thus, depicting it as array of optionals

You can use nils in your array by using Optional types in your array. Just be reminded that you need to use flatMap to return an array of non-optionals and filter out any nils i.e arrayWithNoOptionals.

Array that is optional

Notice question mark is outside of array type. Thus, marking it as an array that is optional. ile array itself has data or nil.

Sort Chinese in swift

http://stackoverflow.com/questions/25685734/incorrect-chinese-number-sort-order-on-ios-using-nslocale-zh-hans-cn

Han collation support:

Pinyin: A B C D …
Stroke: 1 2 3 …
Radical-Stroke: radicals

“if let” optional binding vs “!=nil”

http://stackoverflow.com/questions/29322977/whats-the-difference-between-if-nil-optional-and-if-let-optional

if let optional binding

The if let syntax is called optional binding. It takes an optional as input and gives you back a required constant if the optional is not nil. This is intended for the common code pattern where you first check to see if a value is nil, and if it’s not, you do something with it.

If the optional is nil, processing stops and the code inside the braces is skipped.

optional !=nil

The if optional != nil syntax is simpler. It simply checks to see if the optional is nil. It skips creating a required constant for you.

The optional binding syntax is wasteful and confusing if you’re not going to use the resulting value.

Use the simpler if optional != nil version in that case. It generates less code, plus your intentions are much clearer. The main difference is in readability. Using optional binding creates the expectation that you are going to use the optional that you bind.

Convert Chinese to pinyin in Swift

http://stackoverflow.com/questions/4813086/how-to-convert-chinese-characters-to-pinyin