Skip to content
Permalink
Browse files

First commit

  • Loading branch information...
wangshengjia committed Jan 10, 2016
0 parents commit b95b5d52e43ffd3cdd764083a03c643e42443f34
Showing with 8,911 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. BIN .sass-cache/9cd45e06efd8edb3d3fec9ab3109c1792349cb31/_button.scssc
  3. BIN .sass-cache/9cd45e06efd8edb3d3fec9ab3109c1792349cb31/_global.scssc
  4. BIN .sass-cache/9cd45e06efd8edb3d3fec9ab3109c1792349cb31/_index.scssc
  5. BIN .sass-cache/9cd45e06efd8edb3d3fec9ab3109c1792349cb31/_mixin.scssc
  6. BIN .sass-cache/9cd45e06efd8edb3d3fec9ab3109c1792349cb31/_nav.scssc
  7. BIN .sass-cache/9cd45e06efd8edb3d3fec9ab3109c1792349cb31/_normalize.scssc
  8. BIN .sass-cache/9cd45e06efd8edb3d3fec9ab3109c1792349cb31/_post.scssc
  9. BIN .sass-cache/9cd45e06efd8edb3d3fec9ab3109c1792349cb31/_profile.scssc
  10. BIN .sass-cache/9cd45e06efd8edb3d3fec9ab3109c1792349cb31/_syntax.scssc
  11. +52 −0 _config.yml
  12. +139 −0 _drafts/2016-01-09-properties-in-swift.md
  13. +11 −0 _includes/footer.html
  14. +12 −0 _includes/header.html
  15. +7 −0 _includes/image_caption.html
  16. +12 −0 _includes/pagination.html
  17. +48 −0 _layouts/default.html
  18. +52 −0 _layouts/page.html
  19. +97 −0 _layouts/post.html
  20. +11 −0 _posts/2015-12-22-build-your-cells-in-a-way-of-lego.md
  21. +10 −0 _posts/2015-12-28-run-your-code-snippet-in-Xcode-without-building-the-whole-project.md
  22. +250 −0 _posts/2016-01-08-quiz-about-properties-in-swift.md
  23. +97 −0 _posts/2016-01-08-quiz-answers.md
  24. +10 −0 about.md
  25. +207 −0 assets/css/_button.scss
  26. +270 −0 assets/css/_global.scss
  27. +48 −0 assets/css/_index.scss
  28. +39 −0 assets/css/_mixin.scss
  29. +86 −0 assets/css/_nav.scss
  30. +457 −0 assets/css/_normalize.scss
  31. +405 −0 assets/css/_post.scss
  32. +209 −0 assets/css/_profile.scss
  33. +338 −0 assets/css/_syntax.scss
  34. +13 −0 assets/css/screen.scss
  35. BIN assets/img/authorimage.jpg
  36. +792 −0 assets/js/theme.js
  37. +1 −0 assets/js/theme.min.js
  38. +15 −0 contact.md
  39. +2 −0 css/highlight.pack.js
  40. +108 −0 css/styles/agate.css
  41. +66 −0 css/styles/androidstudio.css
  42. +88 −0 css/styles/arduino-light.css
  43. +73 −0 css/styles/arta.css
  44. +45 −0 css/styles/ascetic.css
  45. +83 −0 css/styles/atelier-cave-dark.css
  46. +85 −0 css/styles/atelier-cave-light.css
  47. +69 −0 css/styles/atelier-dune-dark.css
  48. +69 −0 css/styles/atelier-dune-light.css
  49. +84 −0 css/styles/atelier-estuary-dark.css
  50. +84 −0 css/styles/atelier-estuary-light.css
  51. +69 −0 css/styles/atelier-forest-dark.css
  52. +69 −0 css/styles/atelier-forest-light.css
  53. +69 −0 css/styles/atelier-heath-dark.css
  54. +69 −0 css/styles/atelier-heath-light.css
  55. +69 −0 css/styles/atelier-lakeside-dark.css
  56. +69 −0 css/styles/atelier-lakeside-light.css
  57. +84 −0 css/styles/atelier-plateau-dark.css
  58. +84 −0 css/styles/atelier-plateau-light.css
  59. +84 −0 css/styles/atelier-savanna-dark.css
  60. +84 −0 css/styles/atelier-savanna-light.css
  61. +69 −0 css/styles/atelier-seaside-dark.css
  62. +69 −0 css/styles/atelier-seaside-light.css
  63. +69 −0 css/styles/atelier-sulphurpool-dark.css
  64. +69 −0 css/styles/atelier-sulphurpool-light.css
  65. +64 −0 css/styles/brown-paper.css
  66. BIN css/styles/brown-papersq.png
  67. +60 −0 css/styles/codepen-embed.css
  68. +71 −0 css/styles/color-brewer.css
  69. +63 −0 css/styles/dark.css
  70. +74 −0 css/styles/darkula.css
  71. +77 −0 css/styles/default.css
  72. +97 −0 css/styles/docco.css
  73. +71 −0 css/styles/far.css
  74. +88 −0 css/styles/foundation.css
  75. +73 −0 css/styles/github-gist.css
  76. +99 −0 css/styles/github.css
  77. +89 −0 css/styles/googlecode.css
  78. +101 −0 css/styles/grayscale.css
  79. +83 −0 css/styles/hopscotch.css
  80. +102 −0 css/styles/hybrid.css
  81. +97 −0 css/styles/idea.css
  82. +73 −0 css/styles/ir-black.css
  83. +74 −0 css/styles/kimbie.dark.css
  84. +74 −0 css/styles/kimbie.light.css
  85. +70 −0 css/styles/magula.css
  86. +59 −0 css/styles/mono-blue.css
  87. +83 −0 css/styles/monokai-sublime.css
  88. +70 −0 css/styles/monokai.css
  89. +88 −0 css/styles/obsidian.css
  90. +72 −0 css/styles/paraiso-dark.css
  91. +72 −0 css/styles/paraiso-light.css
  92. +83 −0 css/styles/pojoaque.css
  93. BIN css/styles/pojoaque.jpg
  94. +106 −0 css/styles/railscasts.css
  95. +85 −0 css/styles/rainbow.css
  96. +72 −0 css/styles/school-book.css
  97. BIN css/styles/school-book.png
  98. +84 −0 css/styles/solarized-dark.css
  99. +84 −0 css/styles/solarized-light.css
  100. +102 −0 css/styles/sunburst.css
  101. +75 −0 css/styles/tomorrow-night-blue.css
  102. +74 −0 css/styles/tomorrow-night-bright.css
  103. +74 −0 css/styles/tomorrow-night-eighties.css
  104. +75 −0 css/styles/tomorrow-night.css
  105. +72 −0 css/styles/tomorrow.css
  106. +68 −0 css/styles/vs.css
  107. +93 −0 css/styles/xcode.css
  108. +80 −0 css/styles/zenburn.css
  109. BIN favicon.ico
  110. +29 −0 feed.xml
  111. +40 −0 index.html
  112. BIN media/run_objc_code_1.gif
  113. BIN media/run_swift_code_1.gif
  114. BIN media/run_swift_code_2.gif
@@ -0,0 +1 @@
_site
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,52 @@
# External Gems
gems: [jekyll-paginate]


# Site Settings
title: "Victor S. Wang"
email: "wangshengjia01@gmail.com"
description: "My Blog"
baseurl: ""
homeurl: "http://localhost:4000"
logourl: "/assets/img/bloglogo.jpg"
fa-logo: "fa-bookmark-o"
paginate: 5


# Author Settings
author_name: "Victor Shengjia Wang"
author_url: ""
author_bio: "startup, freelancer, developer, technology enthusiasts, innovation, passion"
author_email: "wangshengjia01@gmail.com"
author_image: "/assets/img/authorimage.jpg"


# Social Settings
twitter_url: "http://twitter.com/wangshengjia"
github_url: "http://github.com/wangshengjia"
linkedin_url: "https://fr.linkedin.com/in/shengjiawang"

# Theme Settings
theme_disqus_shortname: "Victor"
theme_google_comments: false
theme_analytics_id: ""
theme_reading_time: true
theme_autoload_comments: false
theme_always_show_nav: true


# SASS Settings
# DO NOT MODIFY
sass:
sass_dir: "assets/css/"
style: :compressed


# Build Settings
permalink: pretty

markdown: redcarpet
markdown_ext: markdown,mkdown,mkdn,mkd,md

redcarpet:
extensions: ["tables", "autolink", "strikethrough", "space_after_headers", "with_toc_data", "fenced_code_blocks"]
@@ -0,0 +1,139 @@
---
layout: post
title: "Have fun with properties in Swift"
date: 2016-01-09
categories: Swift
banner_image: ""
featured: false
comments: true
---

For years as a developer who using Obj-C every day, we are so familiar with the code below to define a property.

Usually I’d like to suggest to the beginner to always define a property in this way by default (Well.. in recent days, we may also take care a about nullability annotation). Because this is the best practise for most cases, there is no reason to use another approach with “modern” Xcode, such as iVar with synthesized keyword.

<!--more-->
Now with Swift, things are all changed. We totally say goodbye to instance variable. Instead, we now have so many different ways to create and initialise a property. In this blog post, I’d like to walkthrough all the interesting cases about all type of property in Swift. You may use this post as a mini-cheatsheet if you want.

__As always, you can checkout the whole Gist from Github.__

__OK, let’s begin. Enjoy and have fun 🍻🎉🎉__

## A little preparation
Before all, let’s do some preparations first. In order to view clearly how are the properties initialised differently, we make a `Property` type which `print` the value in it’s init() method.

```swift
class Property {
let content: String
init(_ newContent: String) {
content = newContent
print("\(self.content)", terminator: ", ")
}
}
class PropertyCheatSheet { }
```

## I. Stored property
- It can be either initialized in `init()`, in this case it require an explicit type.
- Or it can be set with a value directly, then let the compiler infer the right type.
- Stored property can also be inited in a `lazy` way, which means property4 will be inited only at the first time be accessed

```swift
var property1: Property // mutable property with Property type
let property2: Property // immutable property with Property type
// Property("3") will be called immediatelly, even before property1 & property2 be initialized
let property3 = Property("3")
// A lazy property can only be mutable.
lazy var property4 = Property("4")
init() {
// need to be set a value in initializer
property1 = Property("1")
// even with an immutable property, you still need to set a value for once in initializer
property2 = Property("2")
}
PropertyCheatSheet()
cheatsheet.property4
// => 3, 1, 2, 4,
```

A stored property can also be inited with a closure value. The syntax is a little bit similar as a `computed property` in some cases, but they have totally different behaviours. We'll walkthrough it later.

```swift
// Stored property with closure default value
var property5: Property = {
return Property("5")
}()
// Computed property
var property5: Property {
return Property("5")
}
```

As a stored property with a closure default value:

- Closure will be executed only once at the very beginning.
- It can be immutable, not as `Computed property`.
- We can not access `self` inside closure. Quite make sense since the moment closure executed there is even no `self`.
- It can also be `lazy`, of course in this case it need to be mutable. As return, we can access `self` in the closure.
- Be careful, if you try to access property itself in its own closure, you'll get a infinit loop 😜

```swift
...
let property5 = {
// print(self) -> compile error
return Property("5")
}()
lazy var property6: Property = {
// print(self.property1) -> this is OK
// print(self.property6) -> infinit loop
return Property("6")
}()
...
var cheatsheet = PropertyCheatSheet()
cheatsheet.property4
cheatsheet.property6
// => 3, 5, 1, 2, 4, 6,
```

## II. Computed properties
As the name, `computed property` is kind of property you want to re-compute the value based on the context every time you access it, or set other properties and values indirectly.

- Computed property must have an explicit type.
- Computed property is kind of `lazy`, so it can only use `var` keyword. But it do not means you can actually `assign` the property.
- The `get` block of computed property will be executed every time property be accessed
- Without `set` block, the property is `read-only`
- We can access `self` inside since it is kind of `lazy`. Same as an stored property with closure, if you try to access property itself, then you'll get an infinit loop.

```swift
var property7: Property {
// get {
// print(self.property7) -> infinit loop
return Property("7")
// }
}
```

- If there is a setter, we must give also a getter.
- `newValue` as the default shorthand, can be changed with ohter custom value name.
- Should also be careful with the infinit loop issue.

```swift
// 1. If there is a setter, we must have a getter
// 2. "newValue" as default shorthand, can be changed with set(/* customValueName */) {}
var property8: Property {
get {
return Property(property1.content)
}
set {
// self.property8 = Property("8") -> infinit loop
property1 = Property(property1.content + "_" + newValue.content)
}
}
```

## III. Property observing
@@ -0,0 +1,11 @@
<footer class="wrapper">
<div class="smallnav">
{% for page in site.pages %}
{% if page.title %}<a href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a> &bull;{% endif %}
{% endfor %}
</div>
<div>
Copyright &copy; <a href="{{ site.baseurl }}/">{{ site.title }}</a>. {{ site.time | date: '%Y' }} &bull; All rights reserved.
<span class="ghost">Proudly published with <a href="http://jekyllrb.com/" target="_blank">Jekyll</a>.</span>
</div>
</footer>
@@ -0,0 +1,12 @@
<header class="title">
<a href="{{ site.homeurl }}"><i class="fa {{ site.fa-logo }} fa-lg"></i><span>{{ site.title }}</span></a>
</header>

<nav class="wrapper {% if page.featured == true %} featured {% endif %} {% if site.theme_always_show_nav == true %} alwaysshow {% endif %}">
<a href="#" onclick="return false;"><i class="fa fa-navicon fa-lg"></i></a>
<ul>
{% for page in site.pages %}
{% if page.title %}<li><a href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a></li>{% endif %}
{% endfor %}
</ul>
</nav>
@@ -0,0 +1,7 @@
<div class="container">
<img src="{{ include.imageurl }}" alt="{{ include.description }}"/>
<div class="reference">
<strong>{{ include.title }}</strong>
<p>{{ include.description }}</p>
</div>
</div>
@@ -0,0 +1,12 @@
<div class="pagination">
{% if paginator.next_page %}
<a href="{{ site.baseurl }}/page{{ paginator.next_page }}" class="smallbutton lightgray right"><span>Older Posts</span><i class="fa fa-chevron-right"></i></a>
{% endif %}
{% if paginator.previous_page %}
{% if paginator.previous_page == 1 %}
<a href="{{ site.baseurl }}" class="smallbutton lightgray left"><i class="fa fa-chevron-left"></i><span>Newer Posts</span></a>
{% else %}
<a href="{{ site.baseurl }}/page{{ paginator.previous_page }}" class="smallbutton lightgray left"><i class="fa fa-chevron-left"></i><span>Newer Posts</span></a>
{% endif %}
{% endif %}
</div>
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<title>{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}</title>
<meta name="description" content="{{ site.description }}" />

<meta name="HandheldFriendly" content="True" />
<meta name="MobileOptimized" content="320" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<link rel="alternate" type="application/rss+xml" href="{{ site.baseurl }}/feed.xml">
<link rel="shortcut icon" href="{{ "/favicon.ico" | prepend: site.baseurl }}">
<link rel="prefetch" href="{{ site.baseurl }}">
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl }}">

<link rel="stylesheet" href="{{ "/assets/css/screen.css" | prepend: site.baseurl }}">
<link href='//fonts.googleapis.com/css?family=Domine:700|Open+Sans:400,600|Source+Code+Pro:500' rel='stylesheet' type='text/css'>
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">

<link rel="stylesheet" href="/css/styles/github-gist.css">
<script src="/css/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</head>
<body>

{% include header.html %}

{{ content }}

{% include footer.html %}

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
var config = {
'disqus_shortname': '{{ site.theme_disqus_shortname }}',
'google_comments': {{ site.theme_google_comments }},
'analytics_id': '{{ site.theme_analytics_id }}',
'readingtime': {{ site.theme_reading_time }},
'autoload_comments': {{ site.theme_autoload_comments }}
};
</script>
<script async type="text/javascript" src="{{ "/assets/js/theme.min.js" | prepend: site.baseurl }}"></script>

</body>
</html>
@@ -0,0 +1,52 @@
---
layout: default
---

{% if page.featured == true %}
<div id="cover" class="cover featured">
<div class="background" style="background-image:url('{{ page.banner_image }}');"></div>
<header class="wrapper">
<h2>
{% for category in post.categories %}
{{ category }}
{% endfor %}
</h2>
<h1>{{ page.title }}</h1>
</header>
</div>
{% endif %}

<section class="posts wrapper">
<article class="post {% if page.featured == true %} featured {% endif %}">

<header>
<div class="feature"><span>Featured</span><i class="fa fa-bookmark fa-lg"></i></div>
<h2>
{% for category in post.categories %}
{{ category }}
{% endfor %}
</h2>
<h1 id="posttitle">{{ page.title }}</h1>
</header>

<section class="postbody">
{{content}}
</section>

<footer>
<ul class="share left">
<li><a href="http://twitter.com/share?text={{ page.title }}&url={{ page.url | replace:'index.html','' | prepend: site.homeurl }}" onclick="window.open(this.href, 'twitter-share', 'width=550,height=235');return false;" class="smallbutton lightgray"><i class="fa fa-twitter"></i>Twitter</a></li>
<!-- <li><a href="https://www.facebook.com/sharer/sharer.php?u={{ page.url | replace:'index.html','' | prepend: site.baseurl }}" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;" class="smallbutton lightgray"><i class="fa fa-facebook"></i>Facebook</a></li> -->
</ul>
</footer>

{% if page.comments %}
<div class="comments">
<a href="javascript:;" class="readmore smallbutton blue"><i class="fa fa-comments"></i>View Comments...</a>
<div id="disqus_thread"></div>
<div id="g-comments"></div>
</div>
{% endif %}

</article>
</section>

0 comments on commit b95b5d5

Please sign in to comment.
You can’t perform that action at this time.