<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.6.2">Jekyll</generator><link href="https://qiaolibo.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://qiaolibo.github.io/" rel="alternate" type="text/html" /><updated>2017-12-22T03:02:30+00:00</updated><id>https://qiaolibo.github.io/</id><title type="html">DevQiao</title><subtitle>Keep on hacking</subtitle><author><name>乔黎博</name></author><entry><title type="html">Interaction Design &amp;amp; Collaborative VR</title><link href="https://qiaolibo.github.io/design/InteractionDesign.html" rel="alternate" type="text/html" title="Interaction Design &amp; Collaborative VR" /><published>2017-04-16T16:21:20+00:00</published><updated>2017-04-16T16:21:20+00:00</updated><id>https://qiaolibo.github.io/design/InteractionDesign</id><content type="html" xml:base="https://qiaolibo.github.io/design/InteractionDesign.html">&lt;p&gt;To discover more possibilities in interaction design field, we try to combine different advanced device as mush as we can, to create a realistic experience, even beyond reality, and make the interaction process smoothly.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h1 id=&quot;an-idea-hexagon---solution-driven-approach&quot;&gt;An idea hexagon - Solution-driven approach&lt;/h1&gt;
&lt;h3 id=&quot;finding-the-next&quot;&gt;Finding the neXt&lt;/h3&gt;
&lt;p&gt;The hexagon provide a systematic way to generate many unique solutions
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/hexagon.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;three-principles&quot;&gt;Three principles&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Start with something new, interesting, never seen before.&lt;/li&gt;
  &lt;li&gt;Iterate quick. by looking for variations of solutions and problems.&lt;/li&gt;
  &lt;li&gt;Give up soutions quick.
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/invent_method.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;an-example-of-the-creative-ideas-when-using-camera&quot;&gt;An example of the creative ideas when using camera&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/example.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;rotoscoping&quot;&gt;Rotoscoping&lt;/h3&gt;
&lt;p&gt;An animation technique in which animators trace over footage, frame by frame, for use in live-action and animated movies.
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/rotoscoping.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/rotoscoping2.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;360-camera&quot;&gt;360 Camera&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/3601.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/3602.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/3603.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/3604.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/360.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;oscopen-sound-control&quot;&gt;OSC(Open Sound Control)&lt;/h3&gt;
&lt;h4 id=&quot;arduino-integration&quot;&gt;Arduino integration&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/osc_arduino.gif&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;vibration-actuator&quot;&gt;vibration actuator&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/vibration.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;leap-motion&quot;&gt;Leap Motion&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/leap_motion.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;h4 id=&quot;integrated-into-vr&quot;&gt;Integrated into VR&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/leap_motion2.gif&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;floor-projection&quot;&gt;Floor Projection&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/FloorProjection.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;calibration&quot;&gt;Calibration&lt;/h4&gt;
&lt;p&gt;This transformation is called an extrinsic matrix(外部矩阵) of a camera. This operation is also called homographic transformation(单应变换).
&lt;a href=&quot;http://ksimek.github.io/2012/08/13/introduction/&quot;&gt;点我参考&lt;/a&gt;
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/calibration.png&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/calibration2.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;our-project---one-piece-in-collaborative-vr&quot;&gt;Our Project - One Piece in Collaborative VR&lt;/h1&gt;

&lt;h3 id=&quot;flow-chart&quot;&gt;Flow chart&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/flow.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;lo-fi&quot;&gt;Lo-Fi&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/lo_fi.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;trx-room-setting--hi-fi&quot;&gt;TRX Room Setting &amp;amp; Hi-Fi&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/roomsetting.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/hi_fi.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;final-demo&quot;&gt;Final Demo&lt;/h3&gt;
&lt;p&gt;Finally, we invited our classmates to try our creation which bring a brand new experience.&lt;/p&gt;
&lt;video width=&quot;658&quot; height=&quot;380&quot; src=&quot;/assets/img/2017-01-16-InteractionDesign/IDVR.mp4&quot; controls=&quot;controls&quot;&gt;&lt;/video&gt;

&lt;h3 id=&quot;team-members&quot;&gt;Team members&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-16-InteractionDesign/team.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;</content><author><name>乔黎博</name></author><category term="VR" /><category term="UX" /><summary type="html">To discover more possibilities in interaction design field, we try to combine different advanced device as mush as we can, to create a realistic experience, even beyond reality, and make the interaction process smoothly.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://qiaolibo.github.io/2017-01-16-InteractionDesign/VRs.png" /></entry><entry><title type="html">FatRes - A solution for the sedentary lifestyle</title><link href="https://qiaolibo.github.io/design/FatRes.html" rel="alternate" type="text/html" title="FatRes - A solution for the sedentary lifestyle" /><published>2017-01-10T10:57:16+00:00</published><updated>2017-01-10T10:57:16+00:00</updated><id>https://qiaolibo.github.io/design/FatRes</id><content type="html" xml:base="https://qiaolibo.github.io/design/FatRes.html">&lt;p&gt;Using the “User-centered Interaction Design Process”, this project aim to design a meaningful system to ease the specific people’s sedentary lifestyle.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h1 id=&quot;problem&quot;&gt;Problem&lt;/h1&gt;
&lt;h2 id=&quot;sedentary-lifestyle-will-lead-people-in-the-state-of-sub-health-prematurely-and-sitting-for-a-long-time-will-become-fat&quot;&gt;Sedentary lifestyle will lead people in the state of sub-health prematurely, and sitting for a long time will become fat.&lt;/h2&gt;

&lt;h1 id=&quot;target-population&quot;&gt;Target Population&lt;/h1&gt;
&lt;h2 id=&quot;researchers--graduated-students-who-have-sedentary-lifestyles&quot;&gt;Researchers / graduated students, who have sedentary lifestyles&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-10-FatRes/researchers.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;They read paper for a long time
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/read_paper.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Can flexibly control their time
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/flexible_time_control.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;importance&quot;&gt;Importance&lt;/h1&gt;
&lt;h2 id=&quot;sedentarism-and-obesity-can-cause-cardiovascular-diseases&quot;&gt;Sedentarism and Obesity can cause Cardiovascular diseases&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-10-FatRes/blood_vessel.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;sedentarism-would-form-a-vicious-cycle&quot;&gt;Sedentarism would form a vicious cycle&lt;/h2&gt;
&lt;p&gt;Sedentary lifestyle -&amp;gt; Obesity -&amp;gt; Lazy -&amp;gt; Low efficiency -&amp;gt; Sit for longer time -&amp;gt; Sedentary lifestyle
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/lazy_pusheen.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;stakeholders&quot;&gt;Stakeholders&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Researcher themselves would be healthier&lt;/li&gt;
  &lt;li&gt;boss love efficient researchers
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/happy_boss.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;interview---understanding-users&quot;&gt;Interview - Understanding Users&lt;/h1&gt;
&lt;h3 id=&quot;how-we-recruited-interviewees&quot;&gt;How we recruited interviewees?&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;We find people who are in the same laboratory or friends.&lt;/li&gt;
  &lt;li&gt;We totally recruited 18 interviewees.&lt;/li&gt;
  &lt;li&gt;Most of them are researchers, and only 2 interviewees are engineers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;themes-of-our-questions&quot;&gt;Themes of our questions&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Why did you sit for such a long time then?
    &lt;ul&gt;
      &lt;li&gt;What interrupt you then?
        &lt;ul&gt;
          &lt;li&gt;What did you do after the interruption?&lt;/li&gt;
          &lt;li&gt;Why did you do that?&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Do you know what and how sedentary lifestyle affect you?
    &lt;ul&gt;
      &lt;li&gt;Do you know how to avoid sedentary lifestyle?
        &lt;ul&gt;
          &lt;li&gt;If you don’t know, please come out a method right away.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;What kind of method did you use to avoid sedentary lifestyle?
        &lt;ul&gt;
          &lt;li&gt;Why did you choose that method?&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Did you success?
        &lt;ul&gt;
          &lt;li&gt;Yes: Why did you keep using this method?
            &lt;ul&gt;
              &lt;li&gt;Would you recommand this method to others?&lt;/li&gt;
              &lt;li&gt;How would you recommand it?&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;No: Why can’t you keep using this method?
            &lt;ul&gt;
              &lt;li&gt;What problem did you face?&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;What’s your favorite leisure activity?
    &lt;ul&gt;
      &lt;li&gt;Is this activity need to be done while sitting?&lt;/li&gt;
      &lt;li&gt;Can you do this activity without sitting for a long time?&lt;/li&gt;
      &lt;li&gt;Is there any other leisure activity that need not be done while sitting?&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;model&quot;&gt;Model&lt;/h1&gt;
&lt;h3 id=&quot;what-models-did-we-create-and-use&quot;&gt;What models did we create and use&lt;/h3&gt;
&lt;h4 id=&quot;we-used-the-sequencial-model&quot;&gt;We used the &lt;strong&gt;sequencial&lt;/strong&gt; model&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Primary Intent:&lt;/strong&gt; Using the computer to make ppt or write papers&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trigger:&lt;/strong&gt; When they are at lab and need to work&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Breakdown:&lt;/strong&gt; They need to drink water or go to bathroom&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step:&lt;/strong&gt;
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/uxd_sequense_model.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;affinity-wall---data-interpretation&quot;&gt;Affinity wall - Data Interpretation&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;lowest layer
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/affinity_wall_1.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;higher layers
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/affinity_wall_2.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/affinity_wall_3.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;key-findings--highlights&quot;&gt;Key findings &amp;amp; highlights&lt;/h3&gt;
&lt;h4 id=&quot;red-tag&quot;&gt;Red Tag:&lt;/h4&gt;
&lt;p&gt;The top is that by interrupting the current behavior,interviewees can not only avoid sedentarism but can also increase their working efficiency and concentration.&lt;/p&gt;
&lt;h4 id=&quot;green-tags&quot;&gt;Green Tags:&lt;/h4&gt;
&lt;p&gt;When doing leisure activities, interviewees can be sitting (browsing FB, playing LOL, or watching movies), or not (going out for a walk with friends or exercising).&lt;/p&gt;

&lt;p&gt;Interviewees can avoid sedentary lifestyle by drinking water, going to the restroom, or eating and so on, but can not form the habit of standing up.&lt;/p&gt;

&lt;p&gt;Concentrating on doing something in the suitable environment leads interviewees to sedentary for more than two hours.&lt;/p&gt;

&lt;h1 id=&quot;personas&quot;&gt;Personas&lt;/h1&gt;
&lt;h3 id=&quot;method&quot;&gt;Method&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;We created 4 personas based on our interview data&lt;/li&gt;
  &lt;li&gt;We compared the personas and chose some valuable behavior variables and remove the other less valuable ones&lt;/li&gt;
  &lt;li&gt;We merged the personas into 3 final personas based on their behavior variable distributions&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;behavior-variables-and-distribution&quot;&gt;Behavior Variables and Distribution&lt;/h3&gt;
&lt;p&gt;We use the following attributes to create 7 behavior variables&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Activity:&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;He sits in a chair for almost all day long&lt;/li&gt;
  &lt;li&gt;Sometimes he stands up and walks to bathroom&lt;/li&gt;
  &lt;li&gt;Sometimes he stands up and walks to drink some water&lt;/li&gt;
  &lt;li&gt;He plays games while sitting for an hour&lt;/li&gt;
  &lt;li&gt;He watches videos on Youtube while sitting for half an hour&lt;/li&gt;
  &lt;li&gt;He makes ppt while sitting for 2 hours&lt;/li&gt;
  &lt;li&gt;He prepares enough water before working so that he doesn’t need to stand up to get some water&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Attitude:&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;He knows the disadvantages of sedentary lifestyle, but he is too lazy to stand up&lt;/li&gt;
  &lt;li&gt;He doesn’t like to go outside&lt;/li&gt;
  &lt;li&gt;He doesn’t like to stand up for more than half an hour&lt;/li&gt;
  &lt;li&gt;He wants to concentrate on his work&lt;/li&gt;
  &lt;li&gt;He doesn’t like to do leisure activities while standing up&lt;/li&gt;
  &lt;li&gt;He doesn’t have the habit to stand up, so he can’t change the sedentary lifestyle&lt;/li&gt;
  &lt;li&gt;He wants to concentrate on his work so he doesn’t stand up&lt;/li&gt;
  &lt;li&gt;He is too lazy to stand up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Motivation:&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;He wants to become healthier&lt;/li&gt;
  &lt;li&gt;He wants to concentrate on his work more&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;finally-we-got-7-behavior-variables-and-their-distribution&quot;&gt;Finally, we got 7 behavior variables and their distribution&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;Sitting time (short – long)
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/bvd1.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Standing up reason (physical – mental)
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/bvd2.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Leisure activity (sitting – standing)
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/bvd3.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Danger of sedentism (don’t know – know)
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/bvd4.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Outgoing (no – yes)
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/bvd5.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Stand up frequency (low – high)
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/bvd6.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Personality (lazy – hardworking)
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/bvd7.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;finally-results-of-personas&quot;&gt;Finally results of personas&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-10-FatRes/persona_001.jpeg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/persona_002.jpeg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/persona_003.jpeg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;scenarios&quot;&gt;Scenarios&lt;/h1&gt;
&lt;p&gt;We design a game, FatRes. Players have to walk around to complete missions. The stamina is recovered every 30 minutes with  ringing or vibration on the phone.&lt;/p&gt;
&lt;h3 id=&quot;method-1&quot;&gt;Method&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;We came out with several situations&lt;/li&gt;
  &lt;li&gt;Choose one situation that matches with persona&lt;/li&gt;
  &lt;li&gt;Set up the timing of the events&lt;/li&gt;
  &lt;li&gt;Write down the details of what persona does to complete the scenario&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;finally-results-of-scenarios&quot;&gt;Finally results of scenarios&lt;/h3&gt;
&lt;h4 id=&quot;scenario-1&quot;&gt;Scenario #1&lt;/h4&gt;
&lt;p&gt;As usual, after arriving at his laboratory the first action Kevin takes is sitting on his seat, and then logs in FatRes not only to turn his mind to work but also to get daily reward. The next schedule showing on FatRes is time for teaching assistants.
Because he was appointed as a curricular tutor for this semester, he has responsibility to stay here for following two hours to give a response to any student who has questions. Kevin opens the paper and continues reading from where he marked yesterday.
Until FatRes rings to remind Kevin of that his stamina on the app is recovered, he leaves to the pantry room with his cup to fill it with water. On the way, he feels glad about his  cumulative achievements.
Upon getting back on his seat, he pays attention on paper until there are two students ask him about homework. Before answering their questions, he turns his phone to vibration mode. While their discussion, no one notices the vibration.
Until those two students leave, Kevin notices tips from FatRes and stands up suddenly to answer the following question. Before lunch, he keeps what he does as usual, going to the staff room upon receiving the tips from FatRes, or sometimes going around to the restroom.
Afternoon the FatRes reminds Kevin when one hour earlier than he has an agreement with his classmates to play badminton, he start stretching to warm up before today’s last breakdown .&lt;/p&gt;

&lt;h4 id=&quot;scenario-2&quot;&gt;Scenario #2&lt;/h4&gt;
&lt;p&gt;John walks to his lab and sits in the chair in the morning. He puts his bag on the table and takes out his phone and breakfast. He opens FatRes game in his phone and takes it out with breakfast. FatRes shows that the next chapter of the story is two miles away, so John walks to the place with FatRes’ guide. After reading the latest chapter of story and finishing his breakfast, John walks back to his lab. He puts the phone on the table and sits in the chair. He opens the computer and start programming for two hours. After completing several functions, John decides to take a break and open his phone. The notification of FatRes is showing in the front page, which notices John that there is new chapter of the story available. So John take out his phone and water bottle to read the next chapter and drink some water by the way. With FatRes, John has more motivation to stand up and walk around than before.&lt;/p&gt;

&lt;h4 id=&quot;scenario-3&quot;&gt;Scenario #3&lt;/h4&gt;
&lt;p&gt;Because today is a holiday,Peter opens his computer to watch a movie.He has run out of stamina that there is in the FatRes game.After 30 minutes, his phone rings.He finds that there is enough stamina for playing games.He stands up to fill his cup with water and go to the bathroom.He goes back to watch the movie again.After 30 minutes, his phone rings again.Peter plays the FatRes games.By the way,Peter doesn’t sit down in front of the computer for a long time, and he can stand up regularly.&lt;/p&gt;

&lt;h1 id=&quot;brainstroming--sketching&quot;&gt;Brainstroming &amp;amp; Sketching&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-10-FatRes/brainstroming2.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/brainstroming.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;original-design&quot;&gt;Original Design&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The game will inform the player to stand up periodically and can get points based on how long he stands up, and he can use them to exchange some coupons
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/sketching1.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/sketching2.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The game is a story book. Player should move around to unlock next chapter of the story
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/sketching3.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Player should walk around to save the animals in the virtual world. They can change the scenes when reaching some goals
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/sketching4.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;FatRes is a scheduling tool that reminds user to stand up
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/sketching5.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;feature-selection&quot;&gt;Feature Selection&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;We considered that some users need to work for a continuous period, so we gave up the periodical notification.&lt;/li&gt;
  &lt;li&gt;We like the idea of gathering points and exchanging for something, so we remain this feature and separate it into standing and walking parts.&lt;/li&gt;
  &lt;li&gt;We turned the coupons into stories, clothes, background and music.&lt;/li&gt;
  &lt;li&gt;We turned the idea of changing scenes into traveling cities in the virtual world, and the items in 3 will present the culture of each city the player visits.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;lo-fi-prototype&quot;&gt;Lo-Fi Prototype&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-10-FatRes/lofi1.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/lofi3.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/lofi2.jpg&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/Lo-Fi.gif&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;fatres-lo-fi-prototype-description&quot;&gt;FatRes Lo-Fi Prototype Description&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Player should stand up to get Money (10 gold/min).&lt;/li&gt;
  &lt;li&gt;Player should walk outside the Home to get Distance (1m in game = 1m in real). Walking outside the home will cost stamina (1%/m). Without the stamina, player can not get Distance anymore. Staying in the home will restore the stamina (1%/min).&lt;/li&gt;
  &lt;li&gt;Traveling to other city would cost some Distance.&lt;/li&gt;
  &lt;li&gt;Player can buy stories, clothes, background, background music in store. And these items are related to the city’s culture.&lt;/li&gt;
  &lt;li&gt;Player can decorate his avatar in bag scene.&lt;/li&gt;
  &lt;li&gt;There are two version of stories, normal version and special version. Player can buy all pieces of normal version stories in FatRes. However, player can only buy one piece of special version story of each city, which is random chapter and not knowing total number of chapters. We encourage players to share and discuss their special version stories to the other players.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;feedbacks--design-changes&quot;&gt;Feedbacks &amp;amp; Design Changes&lt;/h1&gt;
&lt;p&gt;In the last milestone, we proposed a prototype as a game. We wanted to use the game to encourage users to stand up and walk around. However, we faced several issues:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;It was too similar to Pokemon Go -&amp;gt; Little value for designing another game for walking&lt;/li&gt;
  &lt;li&gt;Not everyone like to play games -&amp;gt; Narrowed down our target users&lt;/li&gt;
  &lt;li&gt;Users may give up playing the game because of laziness -&amp;gt; Lazy is a big boss&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We tried to use physical feedback to solve the issues.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Everyone needs to drink water&lt;/li&gt;
  &lt;li&gt;No one hates drinking water&lt;/li&gt;
  &lt;li&gt;No one gives up drinking water&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So we came up with a new design, Smart Cup. We want to increase the amount of water the user drinks so that they would have to get up and go to the bathroom more frequently. Finally, we hope the user can form a habit of drinking water and going to the bathroom and hence get rid of sedentary lifestyle.
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/smart_cup.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;key-task&quot;&gt;Key Task&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Remind the user to drink water periodically when the user is not busy&lt;/li&gt;
  &lt;li&gt;Remind the user to stand up and refill the cup with water&lt;/li&gt;
  &lt;li&gt;Let user’s body to inform him/her to go to bathroom&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;design-details&quot;&gt;Design Details&lt;/h3&gt;
&lt;h4 id=&quot;detection&quot;&gt;Detection&lt;/h4&gt;
&lt;p&gt;The cup will detect whether the user is busy or not. If the user is busy, the cup will not notify the user until he/she switches to less important task. If the user is not busy, the cup will notify the user to drink some water every 18 minutes. User can determine the period length&lt;/p&gt;

&lt;h4 id=&quot;notification&quot;&gt;Notification&lt;/h4&gt;
&lt;p&gt;The notification has 2 modes, vocal and vibration
a. The user can select the mode he/she wants to use
b. The system will detect the environment and decide which mode is better to use.
In the vocal mode, the cup will tell the user to drink some water with hierarchical emotional words. For the first time, the cup will tell the user, “it is time to drink some water.” If the user doesn’t drink the water in 30 seconds, the cup will say, “drinking water is good to your health”, “if you don’t drink water, you will get fat!”, “drink it you such a pig!”, separately every 30 seconds.
In the vibration mode, the cup will vibrate to notify the user to drink some water. Similar to vocal mode, the cup will vibrate in a hierarchical pattern. It will vibrate once, twice, 5 times, 5 double vibrates, and continuous vibration separately every 30 seconds.
User should drink at least 100ml or all the water in the cup to turn off the notification.&lt;/p&gt;

&lt;h4 id=&quot;refill&quot;&gt;Refill&lt;/h4&gt;
&lt;p&gt;If the user does not refill the cup after drinking within 2 minutes on the plate, the cup will notify the user to refill it by turning the color of the cup into red. When the user pulls water into the cup, the cup will display how much water in the cup by changing the color outside. If the water level is over the threshold, the cup will beep once to notify the user. Once the cup is put onto the coaster, it starts to count down and detect the user’s state.&lt;/p&gt;

&lt;h4 id=&quot;coupon&quot;&gt;Coupon&lt;/h4&gt;
&lt;p&gt;The user can get one point every time he/she drinks, i.e. drinking 100ml for one point. The user can go to the coupon exchange website via the QR code.&lt;/p&gt;

&lt;h1 id=&quot;hi-fi-prototype&quot;&gt;Hi-Fi Prototype&lt;/h1&gt;
&lt;p&gt;Smart Cup is a system that can remind user to drink some water periodically and when the user is not busy. We want to use the behavior of refilling and going to bathroom to increase the chance the user stands up.&lt;/p&gt;

&lt;h1 id=&quot;usability-test&quot;&gt;Usability Test&lt;/h1&gt;
&lt;h3 id=&quot;goal&quot;&gt;Goal&lt;/h3&gt;
&lt;p&gt;We want to know how our Smart Cup influence the participants’ feeling and efficiency while working or playing, and whether Smart Cup can really solve the sedentary problem.&lt;/p&gt;

&lt;h3 id=&quot;participant-recruitment&quot;&gt;Participant Recruitment&lt;/h3&gt;
&lt;p&gt;We recruited our friends as our participants because they are sedentary researchers, which is our target group. We totally recruited 5 participants.&lt;/p&gt;

&lt;h3 id=&quot;test-setting&quot;&gt;Test Setting&lt;/h3&gt;
&lt;p&gt;We went to participant’s lab or the place he/she likes to work/stay in. We asked the participant to prepare a cup or bottle as a substitution of the Smart Cup, and we researchers pretended the notifier of the Smart Cup.&lt;/p&gt;

&lt;h3 id=&quot;task-procedure&quot;&gt;Task Procedure&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-10-FatRes/stage1.png&quot; alt=&quot;alt text&quot; /&gt;
We described the function of the Smart Cup and our purpose. Participants were instructed to drink some water every 10 minutes, and we would notify them so they didn’t need to worry about it was time up or not. We chose 10 minutes as a period because we don’t want to last the experiment too long.&lt;/p&gt;

&lt;p&gt;There are 2 factors in our usability test, &lt;code class=&quot;highlighter-rouge&quot;&gt;situation&lt;/code&gt; (working or playing) and &lt;code class=&quot;highlighter-rouge&quot;&gt;task&lt;/code&gt; (drink or drink+refill). All participants had to do the tasks of all the conditions. The order of situation is counterbalanced, more specifically, 2 participants started with playing, and 3 participants started with working. The task was in fixed order: drink, drink + refill, drink, drink + refill. This order is simplified but similar to our real drinking behavior.&lt;/p&gt;

&lt;h3 id=&quot;data-collection&quot;&gt;Data Collection&lt;/h3&gt;
&lt;p&gt;After the test, we interviewed the participants about how they feel about the product and the test, and what problem they faced. Also, how the Smart Cup influences their drinking behavior and sedentary lifestyle.&lt;/p&gt;

&lt;h3 id=&quot;findings&quot;&gt;Findings&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Participants usually refill the  cup and go to bathroom at the same time they stand up. Although this may reduce the chance for participants to stand up, we think it can still help participants getting out of sedentary lifestyle.&lt;/li&gt;
  &lt;li&gt;Most participants reported that the Smart Cup can increase the amount of water they drink and the chance to stand up.&lt;/li&gt;
  &lt;li&gt;Most participants reported that they were bothered when Smart Cup interrupted their work or play. Some reported that they can’t continue their reading smoothly after the interruption. Some reported that they lost some immersion  of playing games when interrupted. As previously mentioned, we set 10 minutes as a period because of experiment time, so we didn’t detect the break point of participants. It turns out that detecting break point of the participant is an important feature.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;improvement&quot;&gt;Improvement&lt;/h3&gt;
&lt;p&gt;Based on the usability test, we discussed and came out with the following improvements:
&lt;img src=&quot;/assets/img/2017-01-10-FatRes/stage2.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Improve break point detection. Previously, we only detect whether the user is switching applications or not as a break point. Now we also add the detection of finishing coding of a function, and finishing reading/writing of a paragraph detected by eye-tracker to our break point detect.&lt;/li&gt;
  &lt;li&gt;Customizable water consumption. User can decide how much he/she should drink every time, but it should not be lower than 30ml.&lt;/li&gt;
  &lt;li&gt;Forced notification. If we still can not detect the break point for over an hour, we will notify the user to drink some water no matter how busy the user is. The reason is that we don’t want the user to be too busy to drink water, and that would have no difference from without using Smart Cup. Although the forced notification would bother the user every hour in the worst case, we think getting rid of sedentary lifestyle is more important, and so we add this feature to our system.&lt;/li&gt;
  &lt;li&gt;Remove color changing. We think the user do not need to know how much water remained in the cup. If the cup is empty, the system will inform the user via speech or vibration.&lt;/li&gt;
  &lt;li&gt;Coupon exchange button. We change the QR code to a button that can directly access to the website via the browser in user’s computer.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;h4 id=&quot;smart-cup-has-the-following-features&quot;&gt;Smart Cup has the following features:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Customizable period of water drinking notification countdown.&lt;/li&gt;
  &lt;li&gt;Customizable required consumption.&lt;/li&gt;
  &lt;li&gt;Break point detection.&lt;/li&gt;
  &lt;li&gt;Speech/vibration mode&lt;/li&gt;
  &lt;li&gt;Point collection and coupon exchange.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;final-poster&quot;&gt;Final Poster&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-10-FatRes/fatres_poster.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;exhibition&quot;&gt;Exhibition&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/2017-01-10-FatRes/FinalDemo.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;</content><author><name>乔黎博</name></author><category term="VR" /><category term="UX" /><summary type="html">Using the “User-centered Interaction Design Process”, this project aim to design a meaningful system to ease the specific people’s sedentary lifestyle.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://qiaolibo.github.io/2017-01-10-FatRes/sedentary_obesity.png" /></entry><entry><title type="html">Stack in Swift</title><link href="https://qiaolibo.github.io/Stack.html" rel="alternate" type="text/html" title="Stack in Swift" /><published>2016-06-15T12:04:29+00:00</published><updated>2016-06-15T12:04:29+00:00</updated><id>https://qiaolibo.github.io/Stack</id><content type="html" xml:base="https://qiaolibo.github.io/Stack.html">&lt;p&gt;&lt;strong&gt;栈&lt;/strong&gt;  像是一个有限功能的数组，你只可以通过’push’在栈顶添加一个新的元素，用 &lt;code class=&quot;highlighter-rouge&quot;&gt;pop&lt;/code&gt; 从栈顶移除这个元素，同时 &lt;code class=&quot;highlighter-rouge&quot;&gt;peek&lt;/code&gt; (一瞥)栈顶元素而不弹出（意为只能对栈顶元素执行存取操作）。&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;为什么我们需要这么做？在很多算法中你想将一个元素加入到一个临时列表里，与此同时你希望稍后将它们拉去出来，通常你添加或删除这些元素的顺序是被关心的问题。&lt;/p&gt;

&lt;p&gt;栈结构给了你一个后进先出的顺序（ &lt;strong&gt;LIFO&lt;/strong&gt; ）即 &lt;strong&gt;last-in first-out&lt;/strong&gt; 。 你最后一个push进去的元素就是你在下一次第一个pop出来的元素。（另一个比较相似的结构是 &lt;strong&gt;队列（queue）&lt;/strong&gt; ， 它是FIFO先进先出的。）&lt;/p&gt;

&lt;p&gt;举个栗子，以下代码将一个数字’push’到栈中：&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    stack.push(10)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;现在，当前栈是[10]。接下来在push下一个数字：&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  	  stack.push(3)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;当前栈变为[10， 3]。 再push一个新的数字：&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;	  stack.push(57)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;当前栈是[10, 3, 57]。让我们弹出栈顶元素：&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;	  stack.pop()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;这会返回57，因为它是我们最后一次被push的，现在栈的状态又变回了[10，3]&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;	  stack.pop()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;这将继续返回3。如果栈为空，pop动作返回nil，再另一些实现方式里会抛出错误信息(“stack underflow”)。&lt;/p&gt;

&lt;p&gt;在Swift中，栈很容易被创建。它只是数组的包装。
    public struct Stack&lt;T&gt; {
      fileprivate var array = [T]()&lt;/T&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  public var isEmpty: Bool {
    return array.isEmpty
  }

  public var count: Int {
    return array.count
  }

  public mutating func push(_ element: T) {
    array.append(element)
  }

  public mutating func pop() -&amp;gt; T? {
    return array.popLast()
  }

  public func peek() -&amp;gt; T? {
    return array.last
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;注意push将元素放在数组尾部而不是开始，在数组开头插入元素代价很大，复杂度是 &lt;strong&gt;O(n)&lt;/strong&gt; ，因为这需要在内存中移动数组中的所有元素。而在尾部添加的复杂度为 &lt;strong&gt;O(1)&lt;/strong&gt; ；栈总是花费相同的时间，而无视数组大小或规模（我认为是稳定性）。&lt;/p&gt;

&lt;p&gt;一个有趣的事实是：每次你调用一个方法或者函数，CPU会将返回地址放入一个栈。当函数结束，CPU使用这个返回地址跳回调用者。这就是为什么如果你调用太多函数—例如永不结束的递归函数—你得到一个所谓的栈溢出（stack overflow）错误，原因是CPU栈空间已被用尽。&lt;/p&gt;</content><author><name>乔黎博</name></author><category term="algorithm-in-swift" /><summary type="html">栈 像是一个有限功能的数组，你只可以通过’push’在栈顶添加一个新的元素，用 pop 从栈顶移除这个元素，同时 peek (一瞥)栈顶元素而不弹出（意为只能对栈顶元素执行存取操作）。</summary></entry><entry><title type="html">Swift基础语法（五）</title><link href="https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-%E4%BA%94.html" rel="alternate" type="text/html" title="Swift基础语法（五）" /><published>2016-05-17T15:24:00+00:00</published><updated>2016-05-17T15:24:00+00:00</updated><id>https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95(%E4%BA%94)</id><content type="html" xml:base="https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-%E4%BA%94.html">&lt;p&gt;本篇作为Swift的第四篇，主要介绍了Swift中的枚举类型，它和其它语言相比有其特殊性&lt;/p&gt;

&lt;p&gt;本篇作为Swift的第四篇，主要简述Swift中的属性、方法&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2 id=&quot;属性properties&quot;&gt;属性（Properties）&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Properties are variables and constants that comprise the attributes of a named type.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;可存储属性stored-properties&quot;&gt;可存储属性（stored properties）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;这些属性为每一个实例分配内存，存储其真实的值&lt;/li&gt;
  &lt;li&gt;只有类和结构体可以有stored properties
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;c1&quot;&gt;//Contact有两个存储属性&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Contact&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fullName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;emailAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;//Swift会根据你定义的属性自动创建一个初始化器&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Contact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;fullName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;乔黎博&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;emailAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;qiaolibo@yeah.net&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;//用点语法存取每个属性&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullName&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;email&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emailAddress&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Qiao&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;默认值default-values&quot;&gt;默认值（Default values）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;属性可以设置默认值&lt;/li&gt;
  &lt;li&gt;自动合成的初始化器不会包含默认值，除非你自己声明自己的初始化器
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Work&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Family&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Friend&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Contact&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fullName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;emailAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Friend&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;可计算属性computed-properties&quot;&gt;可计算属性（computed properties）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;这些属性没有为他们实际分配内存，它不存储任何值，而是在 &lt;em&gt;每次存取&lt;/em&gt; 的时候被计算出来，然后返回一个值&lt;/li&gt;
  &lt;li&gt;类、结构体和枚举都可以有computed properties&lt;/li&gt;
  &lt;li&gt;计算属性赋值用花括号（&lt;code class=&quot;highlighter-rouge&quot;&gt;{}&lt;/code&gt;）里的代码段取代等号（&lt;code class=&quot;highlighter-rouge&quot;&gt;=&lt;/code&gt;）&lt;/li&gt;
  &lt;li&gt;存取计算属性和存取存储属性类似
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;c1&quot;&gt;//电视尺寸的结构体&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TV&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// 计算属性&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;diagonal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;aSquared&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bSquared&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;cSquared&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aSquared&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bSquared&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cSquared&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 四舍五入，直接转Int会截断&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;rounded&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rounded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

   &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tv&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;53.93&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;95.87&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;diagonal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;getter和setter&quot;&gt;Getter和Setter&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;如果想要定义setter，则getter必须显示声明，以便区分那个是getter，哪个是setter&lt;/li&gt;
  &lt;li&gt;setter没有地方存值，因此它间接设置存储属性（stored properties）&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;newValue&lt;/code&gt; 关键字代表在赋值时传入的数据
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;diagonal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;//每次设置diagonal时，都会计算并存储height和width&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 默认值&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ratioWidth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ratioHeight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 计算结束后，高度和宽度属性被赋值&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratioHeight&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratioWidth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratioWidth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratioHeight&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratioHeight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratioWidth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratioHeight&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;tv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;diagonal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 34.32...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 61.01...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;类型属性type-properties&quot;&gt;类型属性（Type properties）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;以上属性在每一个实例的属性都是分离的，也就是每一个实例都有各自的属性值，但是在需要这些实例之间共同的属性时就需要Type properties（type itself may also need properties that are common across all instances）&lt;/li&gt;
  &lt;li&gt;在值类型（value-based types like structures）前使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;static&lt;/code&gt; 关键字声明一个Type properties
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;c1&quot;&gt;//游戏关卡的例子，每一关不同状态&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Level&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;highestLevel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;boss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unlocked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;level1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;boss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Chameleon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unlocked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;level2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;boss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Squid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unlocked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;level3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;boss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Chupacabra&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unlocked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;level4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;boss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Yeti&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unlocked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;//存取&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;highestLevel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;level3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highestLevel&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//错误，类型属性不应在实例上存取&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;highestLevel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highestLevel&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;单例模式singleton-pattern&quot;&gt;单例模式（Singleton pattern）&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;Using Singleton is a powerful way to share data between different parts of your code without having to pass the
 data around manually.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;一种实现单例的方法是使用常类型属性 &lt;code class=&quot;highlighter-rouge&quot;&gt;static let&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;必须将单例声明为引用类型，而不是值类型。声明为值类型将不能改变里面的属性
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;c1&quot;&gt;//You must declare a singleton as a reference-type class rather than a value-type structure.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;//If you were to implement one as a structure, then you wouldn't be able to change the values of gameScore and saveState later because the defaultManager property is a constant.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;//When you declare GameManager as a class, only its address in memory is a constant rather than the values themselves.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// You can change the values of gameScore and saveState since GameManager is a reference-type class.&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GameManager&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;defaultManager&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GameManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//默认值值一个新的GameManager实例&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;gameScore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;saveState&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// 私有初始化意味着类实例只被初始化一次，在外部没有其他方法对其初始化&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;属性观察property-observers&quot;&gt;属性观察（Property observers）&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;a way to listen to property changes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;属性监听器（property observers）：&lt;code class=&quot;highlighter-rouge&quot;&gt;willSet {}&lt;/code&gt; 会在属性变化之前调用，&lt;code class=&quot;highlighter-rouge&quot;&gt;didSet {}&lt;/code&gt; 会在属性变化之后调用，用法和 &lt;code class=&quot;highlighter-rouge&quot;&gt;set {}&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;get {}&lt;/code&gt; 类似&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;willSet {}&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;didSet {}&lt;/code&gt;不会在初始化过程中调用，只有当你对一个初始化过的实例赋新值时才会调用，这意味着property observers只会用在可变属性（variable properties），因为常量属性（constant properties）只会在初始化过程中被置值
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Level&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;highestLevel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;boss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unlocked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;didSet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//可以在didSet{}的实现中使用unlocked&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//即使已经在类型里了，也必须写全名：Level.highestLevel而不是highestLevel&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//unlocked是存储属性而不是计算属性，因为没有提供 get {}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unlocked&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highestLevel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;kt&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highestLevel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;限制变量limiting-a-variable&quot;&gt;限制变量（Limiting a variable）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;可以在 &lt;code class=&quot;highlighter-rouge&quot;&gt;willSet&lt;/code&gt; 中使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;newValue&lt;/code&gt;，在 &lt;code class=&quot;highlighter-rouge&quot;&gt;didSet&lt;/code&gt; 中使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;oldValue&lt;/code&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//if the current flowing into the bulb exceeds the maximum value, it will revert to its last successful value.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Notice there's a helpful oldValue constant available in didSet {} so you can access the previous value&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;LightBulb&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;maxCurrent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;currentCurrent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;didSet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currentCurrent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;LightBulb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;maxCurrent&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current too high, falling back to previous setting.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;currentCurrent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;oldValue&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;延迟加载属性lazy-stored-property&quot;&gt;延迟加载属性（lazy stored property）&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;The lazy keyword prevents a value of a stored property from being calculated until your code uses it for the first time. You’ll want to use lazy initialization when a property’s initial value is computationally intensive or when you won’t know the initial value of a property until after you’ve initialized the object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;lazy&lt;/code&gt; 声明这种属性，必须声明为 &lt;code class=&quot;highlighter-rouge&quot;&gt;var&lt;/code&gt; 而不是 &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;（初始化类时lazy属性没有值，用到它时runtime会改变他的值）&lt;/li&gt;
  &lt;li&gt;在下载用户头像或者大量计算时是一种可能的使用情景，只有在被用到时才被计算
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Circle&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;//pi是存储属性&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;//{ }() is the pattern for a closure that is evaluated immediately, and you use it for lazy properties or to add computation to a stored property&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4.0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;atan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;5.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;atan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;239.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4.0&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}()&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//&quot;{}()&quot;代表立即执行，但是声明为lazy后不会立即执行，存取它时它才被计算，但是只被计算一次&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;radius&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;circumference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;radius&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;radius&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;radius&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;radius&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;circle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Circle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;radius&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// got a circle, pi has not been run&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;circumference&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;circumference&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// also, pi now has a value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;方法methods&quot;&gt;方法（Methods）&lt;/h2&gt;</content><author><name>乔黎博</name></author><category term="Swift" /><summary type="html">本篇作为Swift的第四篇，主要介绍了Swift中的枚举类型，它和其它语言相比有其特殊性</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://qiaolibo.github.io/2016-05-17-Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95(%E4%BA%94)/page.jpg" /></entry><entry><title type="html">iOS多线程-GCD使用指南</title><link href="https://qiaolibo.github.io/coding/GCD%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97.html" rel="alternate" type="text/html" title="iOS多线程-GCD使用指南" /><published>2016-05-13T21:46:00+00:00</published><updated>2016-05-13T21:46:00+00:00</updated><id>https://qiaolibo.github.io/coding/GCD%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97</id><content type="html" xml:base="https://qiaolibo.github.io/coding/GCD%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97.html">&lt;p&gt;最近的计步器App涉及异步API，我开始试图将CMPedometer的查询方法封装为一个函数，这个函数可以返回
查询方法得到的结果，方便使用。然而事实却没有这么简单，由于查询方法是异步API，因此只要调用该方法
操作就会被分配到另一个线程去做，因此当查询到结果后，调用这个查询方法的方法早已执行完毕，因此返回空，
也就是除了查询方法自带的回调block中可以取到查询结果，其他地方没法获取查询结果。&lt;/p&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;c1&quot;&gt;// stepsInToday永远取不到值&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;queryPedometerTodayTotalData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
       &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;stepsInToday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
       &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;queryPedometerDataFromDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;toDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pedometerData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
           &lt;span class=&quot;n&quot;&gt;stepsInToday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pedometerData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numberOfSteps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;integerValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
       &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stepsInToday&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;期间试过给 &lt;code class=&quot;highlighter-rouge&quot;&gt;NSOperation&lt;/code&gt; 添加依赖，或者使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_group_async&lt;/code&gt;，但是用这些方法解决异步API
都不奏效，因为异步API操作始终会分去别的线程处理，
我开始的解决办法是在返回前阻塞等待一段时间（如2秒），这样就解决了时序问题，但是这种方式并不好，
试想如果硬件原因（也可能网络应用相关的延迟）超过这个时间段（2秒），则应用崩溃&lt;/p&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;c1&quot;&gt;// 通过延时执行的解决方法&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;queryPedometerTodayTotalData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
       &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;stepsInToday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
       &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;queryPedometerDataFromDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;toDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pedometerData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
           &lt;span class=&quot;n&quot;&gt;stepsInToday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pedometerData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numberOfSteps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;integerValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

       &lt;span class=&quot;nf&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//用于阻塞线程&lt;/span&gt;

       &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stepsInToday&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;今天突然看到一篇博文，恍然大悟，解决了困惑已久的问题&lt;/p&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//通过信号量机制阻塞线程的解决办法&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//注：这个方法会阻塞当前线程，因此应该异步调用，后台让后台线程阻塞无妨&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;queryPedometerTodayTotalData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;stepsInToday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;semaphore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;queryPedometerDataFromDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;toDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pedometerData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;stepsInToday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pedometerData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numberOfSteps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;integerValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_signal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;semaphore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_wait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;semaphore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DISPATCH_TIME_FOREVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stepsInToday&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;至此对GCD有了进一步认识，结合&lt;a href=&quot;http://khanlou.com/2016/04/the-GCD-handbook/&quot;&gt;这篇博文&lt;/a&gt;总结一下:&lt;/p&gt;

&lt;h2 id=&quot;gcd使用指南&quot;&gt;GCD使用指南&lt;/h2&gt;

&lt;h3 id=&quot;后台执行&quot;&gt;后台执行&lt;/h3&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;defaultPriority&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DISPATCH_QUEUE_PRIORITY_DEFAULT&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//该优先级最常用&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;backgroundQueue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_get_global_queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;defaultPriority&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//返回并发队列&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;dispatch_async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backgroundQueue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;doSomeExpensiveWork&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;dispatch_async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dispatch_get_main_queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;//使用 `result` 做各种事&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;可以用 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_queue_create&lt;/code&gt; 创建自己的队列，需指定队列名和类型（串行还是并发）&lt;/li&gt;
  &lt;li&gt;注意，每次调用使用的是 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_async&lt;/code&gt; 而不是 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_sync&lt;/code&gt;。&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_async&lt;/code&gt; 将在block执行前立即返回，而 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_sync&lt;/code&gt; 则会等到block执行完毕后才返回。内部的调用可以使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_sync&lt;/code&gt;（因为不在乎什么时候返回），但是外部的调用必须是 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_async&lt;/code&gt;（否则主线程会被阻塞）&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;创建单例&quot;&gt;创建单例&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_once&lt;/code&gt; 这个 API 可以用来创建单例。不过这种方式在 Swift 中已不再重要，Swift 有更简单的方法来创建单例。这里只贴OC的实现：
``` swift
    &lt;ul&gt;
      &lt;li&gt;(instancetype) sharedInstance {&lt;br /&gt;
//onceToken:该参数是检查后面第二个参数所代表的代码块是否被调用的谓词
static dispatch_once_t onceToken;&lt;br /&gt;
static id sharedInstance;&lt;br /&gt;
dispatch_once(&amp;amp;onceToken, ^{&lt;br /&gt;
  sharedInstance = [[self alloc] init];&lt;br /&gt;
});&lt;br /&gt;
return sharedInstance;&lt;br /&gt;
}
```&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;摊平-completion-block&quot;&gt;摊平 completion block&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;这个部分解决了我近期碰到的问题&lt;/li&gt;
  &lt;li&gt;可以使用信号量来阻塞一个线程任意时间，直到一个信号从另一个线程发出。信号量和 GCD 的其他部分一样是线程安全的，并且能够从任意位置被触发&lt;/li&gt;
  &lt;li&gt;如果想同步执行一个异步API，那可以使用信号量，但是不能修改它
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// 在后台队列&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dispatch_semaphore_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;semaphore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;doSomeExpensiveWorkAsynchronously&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;completionBlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_signal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;semaphore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//下面的方法会阻塞线程，直到 dispatch_semaphore_signal 被调用&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//这就意味着 signal 必须从不同的线程被调用，因为当前线程已经被阻塞。永远都不应该在主线程中调用 wait，只能在后台线程中调用它。&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_wait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;semaphore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DISPATCH_TIME_FOREVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//第二个参数是等待超时时间&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 现在开销很大的异步工作已经完成&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;为什么在已有 completion block 的情况下还要摊平代码？因为方呀，能想到的一种场景是串行执行一组异步程序（即只有前一个任务执行完成，才会继续执行下一个任务）。下面把上述想法简单地抽象成一个 AsyncSerialWorker 类：
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//既然已经使用了 DISPATCH_QUEUE_SERIAL，那么队列中 work 的执行顺序不应该是先进先出的吗？&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//确实是这样，但如果我们把 work 看成是一个耗时的网络操作，其内部是提交到其他线程并发去执行（dispatch_async），也就是每次执行到 work 就立刻返回了，即使最终结果可能还未返回。&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//那么我们想要保证队列中的 work 等到前一个 work 执行返回结果后才执行，就需要 semaphore。例子：&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;typealias&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DoneBlock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;typealias&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;WorkBlock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;DoneBlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AsyncSerialWorker&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;serialQueue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_queue_create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.qiaolibo.serial.queue&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DISPATCH_QUEUE_SERIAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;enqueueWork&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;work&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;WorkBlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;dispatch_async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serialQueue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;semaphore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;work&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
              &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_signal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;semaphore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_wait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;semaphore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DISPATCH_TIME_FOREVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AsyncSerialWorker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enqueueWork&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doneBlock&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;dispatch_async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dispatch_get_global_queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;DISPATCH_QUEUE_PRIORITY_DEFAULT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;arc4random_uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;doneBlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//此时的输出结果为：1，2，3，4，5，如果将关于 semaphore 的代码都注释掉，结果就不会是按顺序输出了。&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//dispatch_semaphore_create(0) 当两个线程需要协调处理某个事件时，我们在这里传入 0；内部其实是维护了一个计数器，下面会说到。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;限制并发的数量&quot;&gt;限制并发的数量&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;在上面的例子中，信号量被用作一个简单的标志，但它也可以当成一个有限资源的计数器。如果想针对某些特定的资源限制连接数，可以这样做：
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;LimitedWorker&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;concurrentQueue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_queue_create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.qiaolibo.concurrent.queue&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DISPATCH_QUEUE_CONCURRENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;semaphore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dispatch_semaphore_t&lt;/span&gt;

  &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;semaphore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;enqueueWork&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;work&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;dispatch_async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;concurrentQueue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_wait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;semaphore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DISPATCH_TIME_FOREVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;work&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;dispatch_semaphore_signal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;semaphore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;在创建信号量时，可以限定资源的可用数。这个可用数（long 类型）会在信号量初始化时作为参数传入。每次等待信号量时，&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_semaphore_wait&lt;/code&gt; 都会消耗一次可用数，如果结果为负，函数会告诉内核阻断你的线程。另一方面，&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_semaphore_signal&lt;/code&gt; 函数每次执行都会将该可用计数 + 1，以此来表明已经释放了资源。如果此刻有因为等待可用资源而被阻隔的任务，系统会从等待的队列中解锁一个任务来执行。&lt;/li&gt;
  &lt;li&gt;这个效果类似 &lt;code class=&quot;highlighter-rouge&quot;&gt;NSOperationQueue&lt;/code&gt; 的 &lt;code class=&quot;highlighter-rouge&quot;&gt;maxConcurrentOperationCount&lt;/code&gt;。如果你使用原生的 GCD 队列而不是 &lt;code class=&quot;highlighter-rouge&quot;&gt;NSOperationQueue&lt;/code&gt;，你就能使用信号量来限制并发任务的数量。&lt;/li&gt;
  &lt;li&gt;每次调用 &lt;code class=&quot;highlighter-rouge&quot;&gt;enqueueWork&lt;/code&gt; 都会将 &lt;code class=&quot;highlighter-rouge&quot;&gt;work&lt;/code&gt; 提交到一个并发队列，而该并发队列收到任务就会丢出去执行，直到触碰到信号量数量耗尽的天花板（&lt;code class=&quot;highlighter-rouge&quot;&gt;work&lt;/code&gt; 入队列的速度太快，&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_semaphore_wait&lt;/code&gt; 已经消耗完了所有的数量，而之前的 &lt;code class=&quot;highlighter-rouge&quot;&gt;work&lt;/code&gt; 还未执行完毕，&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_semaphore_signal&lt;/code&gt; 不能增加信号量的可用数量）&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;等待许多并发任务完成&quot;&gt;等待许多并发任务完成&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;如果你有许多 blocks 任务要去执行，你需要在它们全部完成时得到通知，那可以使用 group。&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_group_async&lt;/code&gt; 允许你在队列中添加任务（&lt;strong&gt;这些任务应该是同步执行的&lt;/strong&gt;，像计步器的异步查询API放这就无效），而且你会追踪有多少被添加的任务。注意：同一个 dispatch group 能够添加不同队列上的任务，并且能保持对所有组内任务的追踪。当所有被追踪的任务完成时，一个传递给 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_group_notify&lt;/code&gt; 的 block 会被触发执行，有点类似于 completion block
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;dispatch_group_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_group_create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;someArray&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nf&quot;&gt;dispatch_group_async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;backgroundQueue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nf&quot;&gt;performExpensiveWork&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;dispatch_group_notify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_get_main_queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// 所有任务都已完成&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;深入细节：&lt;/p&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// 必须在后台队列使用&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dispatch_group_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_group_create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;someArray&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;dispatch_group_enter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;performExpensiveAsyncWork&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;completionBlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;dispatch_group_leave&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;dispatch_group_wait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DISPATCH_TIME_FOREVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 所有任务都已完成&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;和信号量一样，groups 同样保持着一个线程安全的、可以操控的内部计数器。你可以使用这个计数器来确保在 completion block 执行前，多个大开销任务都已执行完毕。使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;enter&lt;/code&gt; 来增加计数器，使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;leave&lt;/code&gt; 来减少计数器。&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_group_async&lt;/code&gt; 已为你处理了这些细节，所以尽情地享受即可&lt;/li&gt;
  &lt;li&gt;代码片段的最后一行是 &lt;code class=&quot;highlighter-rouge&quot;&gt;wait&lt;/code&gt; 调用：它会阻断当前线程并且等计数器到 0 时继续执行。注意，虽然你使用了 &lt;code class=&quot;highlighter-rouge&quot;&gt;enter/leave&lt;/code&gt; API，但你还是能够通过 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_group_notify&lt;/code&gt; 将 block 提交到队列中。反过来也成立：如果你用了 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_group_async&lt;/code&gt; API，也能使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_group_wait&lt;/code&gt;。&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_group_wait&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_semaphore_wait&lt;/code&gt; 一样接收一个超时参数。再次重申，我更喜欢 &lt;code class=&quot;highlighter-rouge&quot;&gt;DISPATCH_TIME_FOREVER&lt;/code&gt;。另外，不要在主线程中调用 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_group_wait&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;上面两段代码最大的区别是，&lt;code class=&quot;highlighter-rouge&quot;&gt;notify&lt;/code&gt; 可以在主线程中调用，而 &lt;code class=&quot;highlighter-rouge&quot;&gt;wait&lt;/code&gt; 只能在后台线程中调用（至少 &lt;code class=&quot;highlighter-rouge&quot;&gt;wait&lt;/code&gt; 部分要在后台线程中调用，因为它会完全阻塞当前线程）&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;隔离队列&quot;&gt;隔离队列&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Swift 中的字典（和数组）都是值类型，当它们被修改时，它们的引用会被一个新的副本所替代。但是，因为更新 Swift 对象的实例变量操作并不是原子性的，所以这些操作不是线程安全的。如果两个线程同一时间更新一个字典（比如都添加一个值），而且这两个操作都尝试写同一块内存，这就会导致内存崩坏。我们可以使用隔离队列来实现线程安全
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//先构建一个标识映射 Identity Map，一个标识映射是一个字典，表示从 ID 到 model 对象的映射&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//标识映射（Identity Map）模式将所有已加载对象放在一个映射中，确保所有对象只被加载一次，并且在引用这些对象时使用该映射来查找对象。&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//在处理数据并发访问时，需要一种策略让多个用户共同操作同一个业务实体，这个很重要。&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//同样重要的是，单个用户在一个长运行事务或复杂事务中始终使用业务实体的一致版本。&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//标识映射模式会为事务中使用所有的业务对象保存一个版本，如果一个实体被请求两次，会得到同一个实体。&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;IdentityMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Identifiable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dictionary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Dictionary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forID&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;addObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;dictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//这个对象基本就是一个字典封装器，如果有多个线程在同一时刻调用函数 addObject，内存将会崩坏，因为线程会操作相同的引用。&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//这也是操作系统中的经典的&quot;读者-写者问题，简而言之，我们可以在同一时刻有多个读者，但同一时刻只能有一个线程可以写入。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;GCD 针对在该场景提供如下四个 API：
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_sync&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_async&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_barrier_sync&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_barrier_async&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;理想的情况是，读操作并发执行，写操作异步执行并且必须确保没有其他操作同时执行。GCD 的 &lt;code class=&quot;highlighter-rouge&quot;&gt;barrier&lt;/code&gt; 集合 API 提供了解决方案：它们会在队列中的任务清空后执行 block。使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;barrier&lt;/code&gt; API 可以限制我们对字典对象的写入，并且确保我们不会在同一时刻执行多个写操作，或者在执行写操作同时执行读操作
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;IdentityMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Identifiable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dictionary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Dictionary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;accessQueue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dispatch_queue_create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.qiaolibo.isolation.queue&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DISPATCH_QUEUE_CONCURRENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;withID&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;dispatch_sync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accessQueue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;addObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;dispatch_barrier_async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accessQueue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;dictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;如上：&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_sync&lt;/code&gt; 将会分发 block 到我们的隔离队列上，然后等待其执行完毕。通过这种方式，我们就实现了同步读操作（如果我们想异步读取，getter 方法就需要一个 completion block）。因为 accessQueue 是并发队列，这些同步读取操作可以并发执行，也就是允许同时读&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_barrier_async&lt;/code&gt; 将分发 block 到隔离队列上，&lt;code class=&quot;highlighter-rouge&quot;&gt;async&lt;/code&gt; 异步部分意味着会立即返回，并不会等待 block 执行完毕。这对性能有好处，但是在一个写操作后立即执行一个读操作会导致读到一个半成品的数据（因为可能写操作还未完成就开始读了）&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_barrier_async&lt;/code&gt; 中 &lt;code class=&quot;highlighter-rouge&quot;&gt;barrier&lt;/code&gt; 部分的逻辑是：barrier block 进入队列后不会立即执行，而是会等待该队列其他 block 执行完毕后再执行。这就保证了我们的 barrier block 每次都只有它自己在执行。而所有在它之后提交的 block 也会一直等待这个 &lt;code class=&quot;highlighter-rouge&quot;&gt;barrier block&lt;/code&gt; 执行完再执行&lt;/li&gt;
  &lt;li&gt;传入 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_barrier_async()&lt;/code&gt; 函数的 queue，必须是 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_queue_create&lt;/code&gt; 创建的并发 queue。如果是串行 queue 或者是 global concurrent queues，这个函数就变成 &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch_async()&lt;/code&gt; 了&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;
&lt;p&gt;GCD 是一个具备底层特性的框架，通过它，我们可以构建高层级的抽象行为。这篇文章较为全面的讲述了 GCD 的相关应用领域，对iOS多线程有了更进一步的认识，其中很多内容还只停留在概念层面，待以后实际运用到再深入理解。&lt;/p&gt;</content><author><name>乔黎博</name></author><category term="GCD" /><category term="iOS" /><summary type="html">最近的计步器App涉及异步API，我开始试图将CMPedometer的查询方法封装为一个函数，这个函数可以返回 查询方法得到的结果，方便使用。然而事实却没有这么简单，由于查询方法是异步API，因此只要调用该方法 操作就会被分配到另一个线程去做，因此当查询到结果后，调用这个查询方法的方法早已执行完毕，因此返回空， 也就是除了查询方法自带的回调block中可以取到查询结果，其他地方没法获取查询结果。 // stepsInToday永远取不到值 func queryPedometerTodayTotalData() -&amp;gt; Int { var stepsInToday = 0 self.queryPedometerDataFromDate(NSDate.today()!, toDate: NSDate()) { (pedometerData, error) in stepsInToday = (pedometerData?.numberOfSteps.integerValue)! } return stepsInToday } 期间试过给 NSOperation 添加依赖，或者使用 dispatch_group_async，但是用这些方法解决异步API 都不奏效，因为异步API操作始终会分去别的线程处理， 我开始的解决办法是在返回前阻塞等待一段时间（如2秒），这样就解决了时序问题，但是这种方式并不好， 试想如果硬件原因（也可能网络应用相关的延迟）超过这个时间段（2秒），则应用崩溃 ``` swift // 通过延时执行的解决方法 func queryPedometerTodayTotalData() -&amp;gt; Int { var stepsInToday = 0 self.queryPedometerDataFromDate(NSDate.today()!, toDate: NSDate()) { (pedometerData, error) in stepsInToday = (pedometerData?.numberOfSteps.integerValue)! }</summary></entry><entry><title type="html">Swift基础语法（四）</title><link href="https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-%E5%9B%9B.html" rel="alternate" type="text/html" title="Swift基础语法（四）" /><published>2016-05-09T16:11:00+00:00</published><updated>2016-05-09T16:11:00+00:00</updated><id>https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95(%E5%9B%9B)</id><content type="html" xml:base="https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-%E5%9B%9B.html">&lt;p&gt;本篇作为Swift的第四篇，主要介绍了Swift中的枚举类型，它和其它语言相比有其特殊性&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2 id=&quot;枚举enumeration&quot;&gt;枚举（enumeration）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;枚举作为一种普通类型（common type），定义了一组 &lt;strong&gt;相关&lt;/strong&gt; 的数据&lt;/li&gt;
  &lt;li&gt;不同于其他语言，&lt;strong&gt;Swift&lt;/strong&gt; 中的枚举中可以拥有方法，属性和协议声明&lt;/li&gt;
  &lt;li&gt;可以用枚举处理响应，存储状态或者包装数据（encapsulate values）
    &lt;blockquote&gt;
      &lt;p&gt;An enumeration can have methods, computed properties and protocol declarations, all while acting as a nice state machine.&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
  &lt;li&gt;用关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;enum&lt;/code&gt; 声明一个枚举
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Month&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;January&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;February&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;March&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;April&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;May&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;June&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;July&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;August&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;September&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;October&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;November&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;December&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//简化版&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Month&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;January&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;February&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;March&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;April&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;May&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;June&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;July&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;August&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;September&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;October&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;November&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;December&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;.&lt;/code&gt; 存取枚举中的内容，利用&lt;strong&gt;Swift&lt;/strong&gt;的类型推导可以省去枚举名
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;schoolSemester&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;month&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Month&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;month&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;August&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;September&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;October&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;November&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;December&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Autumn&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;January&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;February&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;March&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;April&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;May&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Spring&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Not in the school year&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;原始值raw-values&quot;&gt;原始值（Raw values）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;和 &lt;strong&gt;C&lt;/strong&gt; 不同，&lt;strong&gt;Swift&lt;/strong&gt; 不会给枚举指定默认的整型值，但是可以在枚举名后面指定原始值的类型，&lt;em&gt;该类型可以是&lt;code class=&quot;highlighter-rouge&quot;&gt;String&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;Float&lt;/code&gt;或 &lt;code class=&quot;highlighter-rouge&quot;&gt;Character&lt;/code&gt;&lt;/em&gt;，更为灵活，被赋予的raw value也可以是无序的
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//如果省略了第一个之后的默认原始值，则编译器会自增赋值&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Month&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;January&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;February&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;March&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;April&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;May&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;June&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;July&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;August&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;September&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;October&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;November&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;December&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;用枚举实例的 &lt;code class=&quot;highlighter-rouge&quot;&gt;rawValue&lt;/code&gt; 属性来存取原始值（raw value）
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;monthsUntilWinterBreak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;month&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Month&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Month&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;December&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rawValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;month&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rawValue&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;monthsUntilWinterBreak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;April&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;用raw value初始化枚举
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//Enumeration initializers with the rawValue: parameter are failable initializers, meaning if things go wrong, the initializer will return nil.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//这里初始化函数不能保证你赋予的原始值在枚举类型中存在，因此返回一个Optional&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fifthMonth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Month&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rawValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;monthsUntilWinterBreak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fifthMonth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Error: value not unwrapped&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//安全的做法&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fifthMonth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Month&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rawValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;monthsUntilWinterBreak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fifthMonth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// 7&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;关联值associated-values&quot;&gt;关联值（Associated values）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;和原始值（raw value）相似，但是有几点不同
    &lt;ul&gt;
      &lt;li&gt;每一个枚举case可以包含0个或多个关联值&lt;/li&gt;
      &lt;li&gt;每一个case的关联值都有他们自己的类型&lt;/li&gt;
      &lt;li&gt;定义一个关联值和定义一个方法的参数名相似&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;一个枚举可以指定原始值或关联值，但是不能同时指定
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//银行取款的例子，有余额则做计算，余额不足则显示错误信息，这两种操作的结果是不同类型的&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;balance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;WithdrawalResult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;withdraw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;WithdrawalResult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balance&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;balance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;balance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Not enough money!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;withdraw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newBalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Your new balance is: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newBalance&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//存取枚举的关联值在现实生活中的例子很多&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//服务器通常用枚举区分不同类型的请求&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;HTTPMethod&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GET&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;枚举作为状态机enumeration-as-state-machine&quot;&gt;枚举作为状态机（Enumeration as state machine）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;生活中的红绿灯就可以看作一个状态机，同一时刻它只能处在一个状态（前阵子面试被问到状态机我还不知所云。。。囧）&lt;/li&gt;
  &lt;li&gt;枚举类型就可以保证同一时刻只处在同一状态
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TrafficLight&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Yellow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Green&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;trafficLight&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TrafficLight&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Red&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;可选类型optionals&quot;&gt;可选类型（Optionals）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Optional的底层实现就是一个枚举类型&lt;/li&gt;
  &lt;li&gt;可以不通过 &lt;code class=&quot;highlighter-rouge&quot;&gt;?&lt;/code&gt; 声明一个Optional
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;website&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;devqiao.net&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//associated value&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;website&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;No value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Got a value: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;blockquote&gt;
      &lt;p&gt;Swift hides the implementation details with things like if-let binding, the ? and ! operators, and
keywords such as nil.&lt;/p&gt;
      &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// nil和.None在底层是相同的值&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;optionalNil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;optionalNil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// true&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;optionalNil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;None&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;      &lt;/div&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>乔黎博</name></author><category term="Swift" /><summary type="html">本篇作为Swift的第四篇，主要介绍了Swift中的枚举类型，它和其它语言相比有其特殊性</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://qiaolibo.github.io/2016-05-09-Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95(%E5%9B%9B)/page.jpg" /></entry><entry><title type="html">Swift基础语法（三）</title><link href="https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-%E4%B8%89.html" rel="alternate" type="text/html" title="Swift基础语法（三）" /><published>2016-05-02T21:26:25+00:00</published><updated>2016-05-02T21:26:25+00:00</updated><id>https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95(%E4%B8%89)</id><content type="html" xml:base="https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-%E4%B8%89.html">&lt;p&gt;本篇作为Swift的第三篇，主要简述Swift中的结构体和类&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2 id=&quot;结构体structures&quot;&gt;结构体（Structures）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;值类型（value types），直接存取，拷贝赋值，用关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;struct&lt;/code&gt; 声明，建立在内存栈区（stack）&lt;/li&gt;
  &lt;li&gt;许多&lt;strong&gt;Swift&lt;/strong&gt;内建类型都是结构体，如 &lt;code class=&quot;highlighter-rouge&quot;&gt;Int&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;Array&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;Float&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;Double&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;Bool&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;Dictionary&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;Set&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;String&lt;/code&gt;
这是&lt;strong&gt;Swift&lt;/strong&gt;设计的独特之处&lt;/li&gt;
  &lt;li&gt;用 &lt;code class=&quot;highlighter-rouge&quot;&gt;.&lt;/code&gt; （dot syntax）存取结构体成员&lt;/li&gt;
  &lt;li&gt;要修改结构体里声明为 &lt;code class=&quot;highlighter-rouge&quot;&gt;var&lt;/code&gt; 的成员，则该结构体也必须声明为 &lt;code class=&quot;highlighter-rouge&quot;&gt;var&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;用 &lt;code class=&quot;highlighter-rouge&quot;&gt;init&lt;/code&gt; 自定义结构体的初始化函数，如果自定义了，则原来的默认初始化函数将失效，除非自己再定义一遍&lt;/li&gt;
  &lt;li&gt;自定义初始化函数式，所有属性（stored properties）都必须赋初值，&lt;strong&gt;Swift&lt;/strong&gt;不会赋默认初值（定义为let的Optional除外，Optional默认nil）&lt;/li&gt;
  &lt;li&gt;结构体中可以包含方法（method），用 &lt;code class=&quot;highlighter-rouge&quot;&gt;.&lt;/code&gt;调用结构体中的方法&lt;/li&gt;
  &lt;li&gt;用关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;extension&lt;/code&gt; 定义一个拓展，可以拓展结构体/类/枚举的属性和方法。它也允许拓展内建类型&lt;/li&gt;
  &lt;li&gt;结构体比类更快更安全（value semantics and copying）
    &lt;h3 id=&quot;语法&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//结构体声明&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;结构体名&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;100.0&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//可以指定默认值&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;可以为结构体类型&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//结构体实例化&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;结构体名&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;值&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;值&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//Swift会自动生成这类初始化函数&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//存取结构体成员&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;结构体名&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;结构体名&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;子成员&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;类classes&quot;&gt;类（Classes）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;引用类型（reference types），类保存了一个内存指针，建立在内存堆区（heap）&lt;/li&gt;
  &lt;li&gt;通常用结构体代表值，用类代表对象&lt;/li&gt;
  &lt;li&gt;用关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;class&lt;/code&gt; 声明&lt;/li&gt;
  &lt;li&gt;和结构体不同，类不自动提供初始化函数，你必须自己定义，定义方法和结构体一致&lt;/li&gt;
  &lt;li&gt;鉴定对象：&lt;code class=&quot;highlighter-rouge&quot;&gt;===&lt;/code&gt;，检查两个引用类型是否指向同一块内存区&lt;/li&gt;
  &lt;li&gt;类具有可变性（mutability），改变它则在它自身上做改变
结构体一般意味着不可变性（immutability），改变它则意味着得到一个新值&lt;/li&gt;
  &lt;li&gt;存取控制（写在变量前）：
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;public&lt;/code&gt;：模块内和导入的模块均可用&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;internal&lt;/code&gt;：模块内可用，导入的模块不可用，默认值&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;private&lt;/code&gt;：定义所在的本文件内可用，文件级（file level，意味着把不同类定义在同一个文件一样可以存取其他类的private属性）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;struct-or-class-&quot;&gt;Struct or Class ？&lt;/h2&gt;
&lt;h3 id=&quot;struct&quot;&gt;Struct&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;隐含值的拷贝&lt;/li&gt;
  &lt;li&gt;数据语义上不可变&lt;/li&gt;
  &lt;li&gt;在代表值的时候使用，意味着值（value）的改变&lt;/li&gt;
  &lt;li&gt;高效内存分配（stack）
    &lt;h3 id=&quot;class&quot;&gt;Class&lt;/h3&gt;
  &lt;/li&gt;
  &lt;li&gt;隐含共享对象&lt;/li&gt;
  &lt;li&gt;数据语义上可变&lt;/li&gt;
  &lt;li&gt;代表事物的时候使用，意味着状态（state）的改变，有副作用（side effect）&lt;/li&gt;
  &lt;li&gt;较慢的内存分配（heap）&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;类进阶&quot;&gt;类进阶&lt;/h2&gt;
&lt;h3 id=&quot;继承inheritance&quot;&gt;继承（inheritance）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Swift&lt;/strong&gt;是单继承（single inheritance），即只能有一个父类&lt;/li&gt;
  &lt;li&gt;继承的深度没有限制&lt;/li&gt;
  &lt;li&gt;用关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;override&lt;/code&gt; 声明重载函数&lt;/li&gt;
  &lt;li&gt;关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;super&lt;/code&gt; 代指父类，重载时最好先用 &lt;code class=&quot;highlighter-rouge&quot;&gt;super&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;用关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;final&lt;/code&gt; 声明的类将不允许被继承（Preventing inheritance）&lt;/li&gt;
  &lt;li&gt;用关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;final&lt;/code&gt; 声明的方法将不允许被重载&lt;/li&gt;
  &lt;li&gt;子类的初始化方法在初始化本类属性后，调用父类的初始化函数（two-phase initialization）&lt;/li&gt;
  &lt;li&gt;指定初始化和便捷初始化
    &lt;ul&gt;
      &lt;li&gt;关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;required&lt;/code&gt; 标记的初始化函数在子类中必须重载，说明这个初始化函数重要到所有继承链的类都要实现&lt;/li&gt;
      &lt;li&gt;关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;convenience&lt;/code&gt; 标记的初始化函数必须调用同类的其他初始化函数，它最终必须调用指定初始化函数，当需要调用其他初始化函数实现便捷初始化方法时用&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;类的声明周期（lifecycle）：不同于栈上内容出了作用于（scope）的自动释放，在堆上的类不会自动释放
    &lt;ul&gt;
      &lt;li&gt;引用计数（reference counting）/ ARC（automatic reference counting）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;deinit&lt;/code&gt; 声明析构函数，和 &lt;code class=&quot;highlighter-rouge&quot;&gt;init&lt;/code&gt; 不同，&lt;code class=&quot;highlighter-rouge&quot;&gt;deinit&lt;/code&gt; 不是必须的，在对象被清出内存前被调用（&lt;strong&gt;Swift&lt;/strong&gt;在引用计数为0时自动调用，按继承链逐一析构）&lt;/li&gt;
  &lt;li&gt;引用计数造成的负作用–循环引用（retain cycle）导致的内存泄露（memory leak）：用 &lt;code class=&quot;highlighter-rouge&quot;&gt;weak&lt;/code&gt; 声明引起循环引用的属性/变量，默认是 &lt;code class=&quot;highlighter-rouge&quot;&gt;strong&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>乔黎博</name></author><category term="Swift" /><summary type="html">本篇作为Swift的第三篇，主要简述Swift中的结构体和类</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://qiaolibo.github.io/2017-05-02-Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95(%E4%B8%89)/page.jpg" /></entry><entry><title type="html">CoreMotion框架-CMPedometer</title><link href="https://qiaolibo.github.io/coding/CoreMotion%E6%A1%86%E6%9E%B6-CMPedometer.html" rel="alternate" type="text/html" title="CoreMotion框架-CMPedometer" /><published>2016-04-28T09:27:00+00:00</published><updated>2016-04-28T09:27:00+00:00</updated><id>https://qiaolibo.github.io/coding/CoreMotion%E6%A1%86%E6%9E%B6-CMPedometer</id><content type="html" xml:base="https://qiaolibo.github.io/coding/CoreMotion%E6%A1%86%E6%9E%B6-CMPedometer.html">&lt;p&gt;比赛作品涉及计步功能，计步属于健康范畴，当前Apple的HealthKit可以很好的提供健康数据，但是由于涉及隐私，在添加HealthKit时必须要付费的开发者账号，而且包含HealthKit的App审核也更严格。
我目前只需实现简单的计步功能，因此关注到了CoreMotion框架的CMPedometer类，今天简单说说：&lt;/p&gt;

&lt;h2 id=&quot;cmpedometer&quot;&gt;CMPedometer&lt;/h2&gt;
&lt;p&gt;这块国内资料较少，科学上网一阵之后发现 &lt;a href=&quot;https://developer.apple.com/library/ios/documentation/CoreMotion/Reference/CMPedometer_class/index.html&quot;&gt;官方文档&lt;/a&gt;
已经足够清晰明了。顾名思义，该类为了方便获取行走相关数据而设计，除了可用性检查几个关键方法：&lt;/p&gt;

&lt;h3 id=&quot;生成计步器实时数据&quot;&gt;生成计步器实时数据&lt;/h3&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//Swift&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;startPedometerUpdatesFromDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                       &lt;span class=&quot;n&quot;&gt;withHandler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CMPedometerHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;start&lt;/strong&gt;：NSDate类型，指明开始获取数据的时间，不能为空&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;handler&lt;/strong&gt;：传入一个block，每当新数据可用时，这个block在后台线程（异步后台串行队列）重复执行，不能为空&lt;/li&gt;
  &lt;li&gt;App暂停时，计步数据暂停生成，返回前台或后台执行时，计步数据继续生成&lt;/li&gt;
  &lt;li&gt;可用&lt;code class=&quot;highlighter-rouge&quot;&gt;stopPedometerUpdates&lt;/code&gt;停止更新&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;获取历史计步数据&quot;&gt;获取历史计步数据&lt;/h3&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//Swift&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;queryPedometerDataFromDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                             &lt;span class=&quot;n&quot;&gt;toDate&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;withHandler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CMPedometerHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;start&lt;/strong&gt;：NSDate类型，指明开始获取数据的时间，不能为空&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;end&lt;/strong&gt;：NSDate类型，指明结束获取数据的时间，不能为空&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;handler&lt;/strong&gt;：传入一个block，这个block在后台线程（异步后台串行队列，和实时更新方法在同一队列）执行一次，不能为空&lt;/li&gt;
  &lt;li&gt;最多只能获取过去7天的计步数据，如果start参数设置比7天前还早，就只返回可用数据，所以要是做长期分析可能会用到后台服务器&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;cmpedometerhandler&quot;&gt;CMPedometerHandler&lt;/h2&gt;
&lt;p&gt;上面提到的block&lt;/p&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//Swift&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;typealias&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CMPedometerHandler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;CMPedometerData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Void&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;步数主要在&lt;strong&gt;CMPedometerData&lt;/strong&gt;类的&lt;strong&gt;numberOfSteps&lt;/strong&gt;属性里取&lt;/p&gt;

&lt;h2 id=&quot;坑&quot;&gt;坑&lt;/h2&gt;
&lt;p&gt;昨天做了个测试，踩进坑里倒腾了一下午，总结一下：&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;CMPedometer最好声明为一个属性！&lt;/strong&gt;我开始放在viewDidLoad中，声明的临时变量，结果始终取不到数据，报错&lt;code class=&quot;highlighter-rouge&quot;&gt;Error Domain=CMErrorDomain Code=103 &quot;(null)&quot;&lt;/code&gt;。原因就是该方法在启动执行完毕后，临时变量就释放了。对于这样一个持续获取数据的类来说，自然在启动后获取不到数据，这里利用打印block中的error参数可以帮助找到问题&lt;/li&gt;
  &lt;li&gt;实时更新计步数据的方法异步运行在后台串行队列里，因此如果需要实现界面也跟着实时变化，需要异步回主线程更新UI（GCD很便捷），不然只有在停止数据更新时界面才会变&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;最后，stackoverflow要多用！&lt;/p&gt;</content><author><name>乔黎博</name></author><category term="CoreMotion" /><category term="iOS" /><summary type="html">比赛作品涉及计步功能，计步属于健康范畴，当前Apple的HealthKit可以很好的提供健康数据，但是由于涉及隐私，在添加HealthKit时必须要付费的开发者账号，而且包含HealthKit的App审核也更严格。 我目前只需实现简单的计步功能，因此关注到了CoreMotion框架的CMPedometer类，今天简单说说：</summary></entry><entry><title type="html">Swift基础语法（二）</title><link href="https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-%E4%BA%8C.html" rel="alternate" type="text/html" title="Swift基础语法（二）" /><published>2016-04-22T16:33:25+00:00</published><updated>2016-04-22T16:33:25+00:00</updated><id>https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95(%E4%BA%8C)</id><content type="html" xml:base="https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-%E4%BA%8C.html">&lt;p&gt;本篇作为Swift的第二篇，主要简述Swift中的集合类型&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2 id=&quot;集合类型collection-types&quot;&gt;集合类型（Collection Types）&lt;/h2&gt;

&lt;h3 id=&quot;数组arrays&quot;&gt;数组（Arrays）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;有序，元素类型相同，零序（zero-indexed），存储在内存的一段连续存储区&lt;/li&gt;
  &lt;li&gt;一种类型，传值时拷贝&lt;/li&gt;
  &lt;li&gt;空数组：&lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;声明一个不可变数组：
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let numbers: Array&amp;lt;Int&amp;gt;&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let inferredNumbers = Array&amp;lt;Int&amp;gt;()&lt;/code&gt;  //类型推导&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let alsoInferredNumbers = [Int]()&lt;/code&gt;   //简写，常用&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;数组赋初值
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let evenNumber = [2, 4, 6, 8]&lt;/code&gt;       //类型推到&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let allZero = [Int](count: 5, repeatedValue: 0)&lt;/code&gt;   //[0, 0, 0, 0, 0]&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;数组元素的存取
    &lt;ul&gt;
      &lt;li&gt;索引：&lt;code class=&quot;highlighter-rouge&quot;&gt;element[0]&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;使用range：&lt;code class=&quot;highlighter-rouge&quot;&gt;let numbers = numberArray[1...2]&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;数组的操作
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;isEmpty&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;count&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;first&lt;/code&gt; &lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;last&lt;/code&gt; &lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;minElement()&lt;/code&gt; &lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;maxElement()&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;contains(元素)&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;append(元素)&lt;/code&gt; &lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;insert(元素)&lt;/code&gt; &lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;removeLast()&lt;/code&gt; &lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;removeAtIndex(索引)&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;更新：利用索引直接重置对应值，如果用range，超出的部分视为添加元素&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sort()&lt;/code&gt;：返回排序后的数组的拷贝 &lt;code class=&quot;highlighter-rouge&quot;&gt;sortInPlace()&lt;/code&gt;：就地返回排序后的数组&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;for-in&lt;/code&gt; 遍历数组元素&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;序列操作&lt;/strong&gt;（sequence operations）&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;reduce(_:combine:)&lt;/code&gt; &lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;filter(_:)&lt;/code&gt;：按条件过滤元素到新数组 &lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;map(_:)&lt;/code&gt;：对每个元素作指定操作然后映射到新数组&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;字典dictionaries&quot;&gt;字典（Dictionaries）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;无序键值对，一个字典中的键是唯一的，值可以重复出现，所有的键类型相同，所有的值类型相同，hash实现&lt;/li&gt;
  &lt;li&gt;声明一个不可变字典：
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let pairs: Dictionary&amp;lt;String, Int&amp;gt;&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let inferredPairs = Dictionary&amp;lt;Sting, Int&amp;gt;()&lt;/code&gt;  //类型推导&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let alsoInferredNumbers = [String: Int]()&lt;/code&gt;   //简写，常用&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;字典赋初值：&lt;code class=&quot;highlighter-rouge&quot;&gt;let dict = [&quot;A&quot;: 1, &quot;B&quot;: 2, &quot;C&quot;: 3]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;空字典：&lt;code class=&quot;highlighter-rouge&quot;&gt;[:]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;字典元素的存取：
    &lt;ul&gt;
      &lt;li&gt;索引：&lt;code class=&quot;highlighter-rouge&quot;&gt;dict[&quot;A&quot;]&lt;/code&gt; //Optional(1)，不同与数组，如果没有对应键，则返回nil，不会运行时崩溃&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;字典的操作
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;isEmpty&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;count&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;键数组或值数组：&lt;code class=&quot;highlighter-rouge&quot;&gt;Array(dict.keys)&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;Array(dict.values)&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;添加、修改：
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dict.updateValue(值, forKey: 键)&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dict[键] = 值&lt;/code&gt;   //简写&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;删除：
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dict.removeValueForKey(键)&lt;/code&gt;`&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dict[键] = nil&lt;/code&gt;  //简写&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;遍历（使用元组）：&lt;code class=&quot;highlighter-rouge&quot;&gt;for (key, value) in dict&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;序列操作&lt;/strong&gt;参考数组&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;集合sets&quot;&gt;集合（Sets）&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;无序，唯一性，所有元素类型相同，hash实现
    &lt;blockquote&gt;
      &lt;p&gt;&lt;strong&gt;hashing&lt;/strong&gt;：the process of transforming a value - String, Int, Double, Bool, etc - to a numeric value, known as the hash value.&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
  &lt;li&gt;声明集合：
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let set: Set&amp;lt;Int&amp;gt;&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let set = Set&amp;lt;Int&amp;gt;()&lt;/code&gt;  //类型推导&lt;/li&gt;
      &lt;li&gt;空集合：&lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;集合赋初值（与数组共享）：
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let set: Set&amp;lt;Int&amp;gt; = [1, 2, 3, 1]&lt;/code&gt; //不声明类型就会认为是数组，这里1会被视为一个（唯一性）&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let set: Set&amp;lt;Int&amp;gt; = [1, 2, 3, 1]&lt;/code&gt; //类型推导&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;集合的操作：
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;isEmpty&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;count&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;contains(值)&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;first&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;last&lt;/code&gt; 不知道返回哪一个（无序性），但是在集合只有0个或1个元素的时候会比较便捷&lt;/li&gt;
          &lt;li&gt;添加：&lt;code class=&quot;highlighter-rouge&quot;&gt;insert(值)&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;删除：&lt;code class=&quot;highlighter-rouge&quot;&gt;remove(值)&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;遍历：&lt;code class=&quot;highlighter-rouge&quot;&gt;for-in&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;&lt;strong&gt;集合操作&lt;/strong&gt;（set operations）：
            &lt;ul&gt;
              &lt;li&gt;Union：&lt;code class=&quot;highlighter-rouge&quot;&gt;union(_:)&lt;/code&gt; 创建一个新集合，该集合包含两个集合的并集&lt;/li&gt;
              &lt;li&gt;Intersect：&lt;code class=&quot;highlighter-rouge&quot;&gt;intersect(_:)&lt;/code&gt; 创建一个新集合，该集合包含两个集合的交集&lt;/li&gt;
              &lt;li&gt;Subtract： &lt;code class=&quot;highlighter-rouge&quot;&gt;subtract(_:)&lt;/code&gt; 创建一个新集合，该集合包含两个集合的补集&lt;/li&gt;
              &lt;li&gt;Exclusive Or：&lt;code class=&quot;highlighter-rouge&quot;&gt;subtract(_:)&lt;/code&gt; 创建一个新集合，该集合包含两个集合的并集减去交集&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>乔黎博</name></author><category term="Swift" /><summary type="html">本篇作为Swift的第二篇，主要简述Swift中的集合类型</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://qiaolibo.github.io/2016-04-22-Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95(%E4%BA%8C)/page.jpg" /></entry><entry><title type="html">Swift基础语法（一）</title><link href="https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-%E4%B8%80.html" rel="alternate" type="text/html" title="Swift基础语法（一）" /><published>2016-04-22T16:33:25+00:00</published><updated>2016-04-22T16:33:25+00:00</updated><id>https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95(%E4%B8%80)</id><content type="html" xml:base="https://qiaolibo.github.io/coding/Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-%E4%B8%80.html">&lt;p&gt;本篇作为Swift的第一篇，主要简述Swift中的基础数据类型&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2 id=&quot;变量和常量constantsvariables&quot;&gt;变量和常量（Constants&amp;amp;Variables）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Swift&lt;/strong&gt;中用&lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;声明常量，常量在初次赋值后不能再被改变&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Swift&lt;/strong&gt;中用&lt;code class=&quot;highlighter-rouge&quot;&gt;var&lt;/code&gt;声明常量，常量在初次赋值后可以被更改
    &lt;h3 id=&quot;语法&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14159&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;variableNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1_000&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;注：&lt;strong&gt;Swift&lt;/strong&gt;中可以用下划线&lt;code class=&quot;highlighter-rouge&quot;&gt;_&lt;/code&gt;分隔大数字，增加人类可读性，数量和位置随意。
&lt;strong&gt;&lt;em&gt;下划线 &lt;code class=&quot;highlighter-rouge&quot;&gt;_&lt;/code&gt; 还有占位符的作用&lt;/em&gt;&lt;/strong&gt;，代表忽略该项，后面会用到&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;类型转换type-conversion&quot;&gt;类型转换（Type conversion）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;将待转量用小括号括起来再在前面加上想要转成的类型即可：如 &lt;code class=&quot;highlighter-rouge&quot;&gt;Int(doubleNumber)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Swift&lt;/strong&gt;类型要求非常严格，将一个类型的值赋给另一个类型的变量时编译器会报错&lt;/li&gt;
  &lt;li&gt;同样，在两种不同类型的操作数做算数操作时，必须手动强制转换为同一类型变量，否则报错。
这和C++的向高精度自动转换有区别
    &lt;h3 id=&quot;语法-1&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;integer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;12.5&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decimal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;元组tuples&quot;&gt;元组（Tuples）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;多个成组或多个相关的元素可以声明为元组&lt;/li&gt;
  &lt;li&gt;用&lt;code class=&quot;highlighter-rouge&quot;&gt;.&lt;/code&gt;访问元组中的元素，如果没有指定索引值，则默认为从0开始的数字索引
    &lt;h3 id=&quot;语法-2&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//默认索引值的元组，从0开始&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coordinates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coordinates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coordinates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//定义索引值的元组&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coordinates3D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coordinates3D&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coordinates3D&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coordinates3D&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coordinates3D&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//同上三句&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;类型推导type-inference&quot;&gt;类型推导（Type inference）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Swift&lt;/strong&gt;具有类型推导特性，在声明变量时可以省略类型声明，系统会自动判断变量的类型&lt;/li&gt;
  &lt;li&gt;在Xcode中按住option单击或三指点击未声明类型的变量可以查看系统推导的类型
    &lt;h3 id=&quot;语法-3&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;typeInferredInt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;操作符operations&quot;&gt;操作符（Operations）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Swift&lt;/strong&gt;的算数操作符和其他语言相似：&lt;code class=&quot;highlighter-rouge&quot;&gt;+&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;-&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;*&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;/&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;gt;&amp;gt;&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;+=&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;-=&lt;/code&gt;……&lt;/li&gt;
  &lt;li&gt;比较操作符：&lt;code class=&quot;highlighter-rouge&quot;&gt;==&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;!=&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;gt;=&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;=&lt;/code&gt;……&lt;/li&gt;
  &lt;li&gt;布尔类型（&lt;code class=&quot;highlighter-rouge&quot;&gt;Bool&lt;/code&gt;）及逻辑操作符：&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;||&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;!&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;用小括号&lt;code class=&quot;highlighter-rouge&quot;&gt;()&lt;/code&gt;设定操作优先级
    &lt;h3 id=&quot;语法-4&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;subtract&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;multiply&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;divide&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;modulo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;11.6&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//0.8  Swift可以对小数求余&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;shiftLeft&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;//位移操作将十进制数的二进制形式位移后再返回十进制结果&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;字符串strings&quot;&gt;字符串（Strings）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Character&lt;/code&gt;类型存储单一字符，&lt;code class=&quot;highlighter-rouge&quot;&gt;String&lt;/code&gt;类型用来存储一串字符&lt;/li&gt;
  &lt;li&gt;字面量（string literal）：用双引号括起来的字符&lt;/li&gt;
  &lt;li&gt;串接（Concatenation）：&lt;code class=&quot;highlighter-rouge&quot;&gt;+&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;+=&lt;/code&gt; 可以用来连接多个字符串&lt;/li&gt;
  &lt;li&gt;插入（Interpolation）：在字面量双引号中用&lt;code class=&quot;highlighter-rouge&quot;&gt;\(插入内容)&lt;/code&gt;插入内容&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;==&lt;/code&gt; 符可以用作字符串判等，&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&lt;/code&gt; 用作字符串比较时依据字母表序位置先后判断结果
    &lt;h3 id=&quot;语法-5&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;exclamationMark&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Character&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;!&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;sentence&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exclamationMark&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//&quot;Hello!&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Qiao&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;sayHi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello my name is &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;!&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;guess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;dog&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dogEqualsCat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;guess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cat&quot;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//false&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;order&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cat&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;dog&quot;&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;//true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;控制语句control-flow&quot;&gt;控制语句（Control flow）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;if&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;if - else&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;if - else if - else&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;三元控制符：&lt;code class=&quot;highlighter-rouge&quot;&gt;(&amp;lt;CONDITION&amp;gt;) ? &amp;lt;TRUE VALUE&amp;gt; : &amp;lt;FALSE VALUE&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;switch &amp;lt;CONDITION&amp;gt; case: case: default:&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;模式匹配（pattern matching）：&lt;code class=&quot;highlighter-rouge&quot;&gt;let-where&lt;/code&gt; 语法
    &lt;h3 id=&quot;语法-6&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Even&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Odd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//部分匹配（partial matching）&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coordinates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coordinates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 1&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Origin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 2&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;On the x-axis.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 3&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;On the y-axis.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 4&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;On the z-axis.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// 5&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Somewhere in space&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//保留对应值的部分匹配&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coordinates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coordinates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Origin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;On the x-axis at x = &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;On the y-axis at y = &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;On the z-axis at z = &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Somewhere in space at x = &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;, y = &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;, z = &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coordinates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coordinates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Along the y = x line.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Along the y = x^2 line.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;范围ranges&quot;&gt;范围（Ranges）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;闭区间（closed range）   ： &lt;code class=&quot;highlighter-rouge&quot;&gt;...&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;开区间（half-open range）： &lt;code class=&quot;highlighter-rouge&quot;&gt;..&amp;lt;&lt;/code&gt;
    &lt;h3 id=&quot;语法-7&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;closedRange&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//范围从0到5，包括5&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;halfOpenRange&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//范围从0到4，不包括5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;循环loops&quot;&gt;循环（Loops）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;for-in&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;while&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;repeat-while&lt;/code&gt;：类似于其他语言的&lt;code class=&quot;highlighter-rouge&quot;&gt;do-while&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;用 &lt;code class=&quot;highlighter-rouge&quot;&gt;break&lt;/code&gt; 退出循环， &lt;code class=&quot;highlighter-rouge&quot;&gt;continue&lt;/code&gt; 继续下一次循环&lt;/li&gt;
  &lt;li&gt;标签语句（Labeled statements）：和 &lt;code class=&quot;highlighter-rouge&quot;&gt;continue&lt;/code&gt; 配合使用，可以使程序跳到指定语句，
类似C中的 &lt;code class=&quot;highlighter-rouge&quot;&gt;goto&lt;/code&gt;
    &lt;h3 id=&quot;语法-8&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//for循环&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;VARIABLE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;RANGE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;LOOP&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CODE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//while循环&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;CONDITION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;LOOP&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CODE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//repeat-while循环&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;repeat&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;LOOP&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CODE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;CONDITION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//标签语句&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;rowLoop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;columnLoop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rowLoop&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;column&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;函数functions&quot;&gt;函数（Functions）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;用 &lt;code class=&quot;highlighter-rouge&quot;&gt;func&lt;/code&gt; 关键字声明函数&lt;/li&gt;
  &lt;li&gt;可以在第二个或后续参数标签前指明一个外部标签，在调用时可以使代码更为简洁&lt;/li&gt;
  &lt;li&gt;返回值用 &lt;code class=&quot;highlighter-rouge&quot;&gt;-&amp;gt;&lt;/code&gt; 接在函数声明后面，可以返回元组&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Swift&lt;/strong&gt;的参数传递是值传递（pass-by-value），在传入参数前做一次拷贝，函数体内可以看成是let，
内部改变不会影响外部，如果要用引用传参（pass-by-reference）需要在参数前加 &lt;code class=&quot;highlighter-rouge&quot;&gt;inout&lt;/code&gt; 关键字，
声明为引用传参的函数在调用时参数前要加 &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt;,以指明这是引用方式&lt;/li&gt;
  &lt;li&gt;函数可以作为变量传递声明时类似于 &lt;code class=&quot;highlighter-rouge&quot;&gt;var function: (Int, Int) -&amp;gt; Int&lt;/code&gt;
    &lt;h3 id=&quot;语法-9&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;函数名&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;第一个参数标签&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;参数类型&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;指定的参数外部标签&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;参数标签&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;参数类型&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;参数默认值&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;函数返回值&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;函数体&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;返回值&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;闭包closures&quot;&gt;闭包（Closures）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;可以理解为匿名函数&lt;/li&gt;
  &lt;li&gt;闭包可以“捕获”作用域内的变量，任何对其改变都会在闭包内外收到影响
    &lt;h3 id=&quot;语法-10&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//闭包声明&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;multiplyClosure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//和函数类型的变量基本一致&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//闭包赋值&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;multiplyClosure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//闭包使用&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;multiplyClosure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;//result=8&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//闭包简化语法&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//如果只有一句表达式，可以省略return&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//利用类型推倒机制，在已经声明过的前提下可以省略返回类型和参数类型&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//参数列表：参数可以用从0开始的序列引用&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;multiplyClosure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//尾闭包语法（trailing closure syntax）&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//当一个闭包作为函数的最后一个参数时, 尾闭包可以化简代码&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//原来&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;operateOnNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//尾闭包&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;operateOnNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;可选类型optional&quot;&gt;可选类型（Optional）&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Nil代表空（absence of value）&lt;/li&gt;
  &lt;li&gt;很多语言用哨兵值（Sentinel values）代表空值，例如0代表没有，但是容易引起歧义，对于这个0
不同人有不同理解，因此&lt;strong&gt;Swift&lt;/strong&gt;引入和Optionals类型&lt;/li&gt;
  &lt;li&gt;Optional可以被类比为一个盒子，它可以包含一个值，也可以为空，用 &lt;code class=&quot;highlighter-rouge&quot;&gt;?&lt;/code&gt; 声明：&lt;code class=&quot;highlighter-rouge&quot;&gt;var errorCode: Int?&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Optional强制拆包（force unwrapping）：用 &lt;code class=&quot;highlighter-rouge&quot;&gt;!&lt;/code&gt; 跟在可选类型变量后。一般不推荐这种做法，
强制拆包会，如果值为空，可能会引起运行时crash&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;if let binding&lt;/code&gt;：这种方式较为安全的存取Optional&lt;/li&gt;
  &lt;li&gt;nil coalescing： 当拆包一个Optional为nil时，用 &lt;code class=&quot;highlighter-rouge&quot;&gt;??&lt;/code&gt; 指定默认值
    &lt;h3 id=&quot;语法-11&quot;&gt;语法&lt;/h3&gt;
    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//一次拆包多个值&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;authorName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Qiao&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;authorAge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;authorName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;authorAge&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;The author is &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; who is &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; years old.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;No author or no age.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//nil coalescing&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optionalInt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>乔黎博</name></author><category term="Swift" /><summary type="html">本篇作为Swift的第一篇，主要简述Swift中的基础数据类型</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://qiaolibo.github.io/2016-04-22-Swift%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95(%E4%B8%80)/page.jpg" /></entry></feed>