-
Notifications
You must be signed in to change notification settings - Fork 149
/
5. Drawing.srt
7888 lines (6217 loc) · 203 KB
/
5. Drawing.srt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1
00:00:00,401 --> 00:00:04,403
本字幕由志愿者义务贡献,采用许可协议
知识共享 署名-非商业性使用-相同方式共享 3.0 美国
2
00:00:04,472 --> 00:00:09,340
Stanford University. >> All right, well,
斯坦福大学
3
00:00:09,409 --> 00:00:13,878
welcome to Lecture 5 then of CS193P this Fall of 2017.
欢迎参加 2017 年秋季学期斯坦福 CS193P 的第五节课
4
00:00:13,947 --> 00:00:16,981
So I'm gonna take just a few minutes of the beginning here
我会在这节课的开始花上几分钟来
5
00:00:17,050 --> 00:00:19,818
to go over just a couple of more little Swift things.
讲讲更多的关于 Swift 的知识
6
00:00:19,887 --> 00:00:21,786
These are actually in your reading assignment for
它们实际上是在你们这周的阅读任务中的
7
00:00:21,855 --> 00:00:25,090
this week. So I'm really just kinda emphasizing these
因此我只会强调一下这些东西
8
00:00:25,158 --> 00:00:28,693
things, then we're gonna dive into our main topic today
接着我们就会进入我们今天的主题的学习
9
00:00:28,762 --> 00:00:33,098
which is views, drawings, how you do custom drawing in iOS.
那就是视图和画图(views, drawings)如何在 iOS 上画东西
10
00:00:33,166 --> 00:00:36,968
And I'm gonna start with a huge demo, the only thing I'm
并且我会写一个非常大的示例程序
11
00:00:37,037 --> 00:00:40,872
gonna probably be able to do today is the model of our MVC.
我今天应该只能写完我们 MVC 中的模型(Model)
12
00:00:40,940 --> 00:00:43,408
But that's gonna allow me to show you an example of enum,
我可以用这个来给你们看看枚举类型的例子
13
00:00:43,477 --> 00:00:45,677
which we didn't get to work into concentration.
我们没有在 Concentration 中使用枚举类型
14
00:00:45,746 --> 00:00:49,981
So you only theoretically know enum, and we'll be actually do
所以你们只是在理论上熟悉枚举类型,我们这节课会
15
00:00:50,050 --> 00:00:53,918
enum. All right, so let's do these little minor things.
实际使用枚举类型。让我们开始这些小块知识的学习
16
00:00:53,987 --> 00:00:56,455
One of them is error handling in Swift.
其中一个是 Swift 的错误处理(error handling)
17
00:00:56,523 --> 00:00:58,757
Now, a lot of times you'll have an error and
很多时候你会得到一个错误
18
00:00:58,825 --> 00:01:01,626
it will be something that kind of, could be expected or
而这些错误在某种意义上是可以被预测的
19
00:01:01,695 --> 00:01:04,596
anticipated. You know, you do something over the network and
比如说,你用网络做些是什么
20
00:01:04,664 --> 00:01:06,131
there might be a network time out,
你可能就会得到连接超时的错误
21
00:01:06,200 --> 00:01:07,599
that's kind of a normal error.
这是非常常见的错误
22
00:01:07,668 --> 00:01:10,135
If you have that kind of error, you likely would have
如果你得到了这样的错误,你可能会
23
00:01:10,204 --> 00:01:12,136
an argument to the function that goes and
向这个函数中传入一个参数
24
00:01:12,205 --> 00:01:15,507
does that network call. Maybe it's even a closure that calls
并且让它来负责网络的调用,那个参数甚至可以是一个闭包
25
00:01:15,575 --> 00:01:19,177
you back and said, I found this somewhat expected error.
它返回并说,我找到了这个预计的错误
26
00:01:19,246 --> 00:01:22,513
But sometimes you have errors that you don't expect or
但有的时候你会有一些你没有预料的的错误
27
00:01:22,582 --> 00:01:25,783
that are kind of rare, and really disrupt the usage of
或者一些很罕见的错误,它们可能会中断一个函数的调用
28
00:01:25,852 --> 00:01:30,021
a method or whatever. And in that kind of error,
或者其他什么。对于这样的错误
29
00:01:30,090 --> 00:01:33,057
instead of having to have one of your arguments be an error
我们不需要用我们的一个参数作为错误处理器
30
00:01:33,126 --> 00:01:35,927
handler or returning an error, or something like that.
或者说返回一个错误,或其他类似的做法
31
00:01:35,996 --> 00:01:39,030
You can do something that's called throwing an error.
你可以直接抛出(throw)一个错误
32
00:01:39,099 --> 00:01:39,998
Now, in other languages,
在其他语言中
33
00:01:40,067 --> 00:01:42,300
you might think of this as like raising exceptions or
你可能会认为这就是抛出一个异常
34
00:01:42,369 --> 00:01:44,469
something like that. It's a little simpler and
或其他类似的东西,但在 Swift 编程中
35
00:01:44,537 --> 00:01:47,372
more elegant when you design in Swift. It's as simple as
这会更加的简单优雅。它就像这样
36
00:01:47,441 --> 00:01:50,174
this, a method that could get an error, okay,
一样简单:一个可能会得到一个错误的函数
37
00:01:50,243 --> 00:01:53,578
a significant error that would disrupt what it's doing,
这个错误可能会打断我们正在执行的任务
38
00:01:53,647 --> 00:01:56,848
can decide that it throws errors. And you see these
而可能得到错误的函数可以选择要抛出这个错误
39
00:01:56,917 --> 00:01:59,417
methods very clearly because when they're declared, they'll
你可以很简单地辨别出这些函数,因为当它们被声明时
40
00:01:59,486 --> 00:02:03,555
have the word throws at the end. So this function save
它们的末尾会有 throws 关键字,那么这样的函数
41
00:02:03,623 --> 00:02:07,025
throws. Okay, if it gets an error, it throws this error.
会保存 throws,如果它得到了一个错误,它会抛出那个错误
42
00:02:07,094 --> 00:02:11,263
Now, when it throws an error at you, you need to catch it.
那么,当它抛出一个错误的时候,你需要接住(catch)它
43
00:02:11,331 --> 00:02:12,998
Okay, and you catch this error and
当你接住错误后
44
00:02:13,066 --> 00:02:15,066
then you can look at it and decide what to do. So
你可以看看它是啥,并且决定要做什么
45
00:02:15,135 --> 00:02:18,036
how do you catch an error that has thrown? Well,
那么,你要如何接住函数抛出的错误呢?
46
00:02:18,105 --> 00:02:22,674
you do that by putting this do catch construct around your
你可以通过将这个 do catch 结构
47
00:02:22,743 --> 00:02:27,345
call to the method that might throw. And you say, try, in
放在那个可能会抛出错误的函数的旁边
48
00:02:27,414 --> 00:02:31,382
front of the call. So you're going to try this method
并且在函数调用前使用 try 关键字,这样表示你会试着调用这个函数
49
00:02:31,451 --> 00:02:34,552
that it might throw. But since you've put it inside this do,
但它可能会抛出错误,但因为你一进将这个调用放在了这个 do catch 中
50
00:02:34,621 --> 00:02:37,322
catch thing, that thing you see up there, you're going to
就像我们幻灯片里写的那个
51
00:02:37,390 --> 00:02:40,292
catch that error. Okay, so it's as simple as that.
你会去接住那个错误,就是这么简单
52
00:02:40,361 --> 00:02:43,161
So, any method that throws has to be called with try.
所有可能会抛出错误的函数必须要用 try 来调用
53
00:02:43,229 --> 00:02:45,897
Okay, you have to let Swift know I understand that this
你要让 Swift 知道你了解这个函数可能会抛出错误
54
00:02:45,966 --> 00:02:47,666
can throw, and so I'm trying it.
所以你正在尝试调用它
55
00:02:47,734 --> 00:02:50,168
But it doesn't necessarily have to be kept, caught,
但实际上那个被抛出的错误不一定必须要被接住
56
00:02:50,237 --> 00:02:53,638
and I'll show you in a second how to do it without catching.
等一下我就给你们展示如何不接住那个错误
57
00:02:53,707 --> 00:02:56,474
If you do wanna catch, then you do this do catch, and
如果你想要接住错误,你就要用这个 do catch 结构
58
00:02:56,543 --> 00:02:59,778
in the catch you notice there's the green, let error.
并注意到在 catch 部分的代码中有一段绿色的 let error
59
00:02:59,847 --> 00:03:02,914
Okay, that little error thing, it's just a local variable.
这个 error 它就是一个局部变量
60
00:03:02,983 --> 00:03:05,517
That's the thing that gets thrown at you, okay,
它就是那个函数抛出来的错误时
61
00:03:05,585 --> 00:03:08,353
when it throws an error. And it's going to be
所抛出的错误,而这个 error 是实现了
62
00:03:08,421 --> 00:03:12,190
something that implements the protocol error, but
Error 这个协议的
63
00:03:12,259 --> 00:03:14,259
there's actually nothing in that protocol.
但实际上那个协议中什么都没有
64
00:03:14,328 --> 00:03:17,262
It just identifies, it's just typing this thing as error.
它只是用来确认这个东西的类型是 Error
65
00:03:17,330 --> 00:03:20,732
Now, in iOS when things, errors gets thrown at you,
在 iOS 中,当你得到错误的时候
66
00:03:20,801 --> 00:03:23,234
there almost always going to be NSErrors.
那些错误绝大多数都会是 NSError
67
00:03:23,303 --> 00:03:26,271
So an NSError is just a class, it implements the Error
NSError 是一个实现了 Error 协议的一个类
68
00:03:26,340 --> 00:03:29,741
protocol which is to say that, that nothing in particular.
Error 这个协议并没有做什么
69
00:03:29,810 --> 00:03:32,277
But NSError has a lot of nice methods and vars,
但是 NSError 这个类中有许多有用的函数和变量
70
00:03:32,346 --> 00:03:35,213
like the error code, even a localized description of
比如说错误代码,它甚至有本地化的错误描述
71
00:03:35,282 --> 00:03:37,582
the error that you could present to a user,
你可以直接将这个本地化的错误描述呈现给用户
72
00:03:37,651 --> 00:03:40,752
for example. So the way this goes is if you had a function
那么如果你有一个
73
00:03:40,821 --> 00:03:41,686
save that throws,
可以抛出错误地函数
74
00:03:41,755 --> 00:03:44,155
you're gonna go looking in its documentation and
你要去看看文档并
75
00:03:44,224 --> 00:03:47,693
see what kind of NSError stuff it can throw. And it'll throw
确定哪些类型的 NSError 是它能抛出的,它可能会抛出
76
00:03:47,761 --> 00:03:50,127
certain errors like save, the save maybe it's for
一些特定类型的错误,比如对于 save 函数
77
00:03:50,196 --> 00:03:52,964
saving into a database and the disk is full, so the database
它可能想要向数据库保存数据,但我们的磁盘已经满了
78
00:03:53,033 --> 00:03:55,333
couldn't save so maybe there's an error code for
因此数据库无法保存,那么这里就可能会有一个关于
79
00:03:55,402 --> 00:03:58,169
disk full or whatever. So this is what you do if you want to
磁盘已满的错误,或其他什么。那么这就是你如何
80
00:03:58,238 --> 00:04:00,906
catch a thrown error and kind of handle it, look at it,
接住一个被抛出的错误,并且处理它
81
00:04:00,974 --> 00:04:05,410
see what it is, decide what to do. But you can just say,
看看它是啥,决定要做什么。但你也可以只写
82
00:04:05,479 --> 00:04:09,814
try!, and what that means is, try this and
try! 这就意味着,尝试调用这个函数
83
00:04:09,883 --> 00:04:12,583
if it throws crash my app. Now,
如果它抛出一个错误,那就让我的程序崩溃
84
00:04:12,652 --> 00:04:15,887
you would only do this if you were 100% certain that,
你们应当只在你们 100% 确定
85
00:04:15,956 --> 00:04:19,323
that thing could not throw in the circumstance that you're
在你们调用这个函数的情境下,它不会抛出错误
86
00:04:19,392 --> 00:04:22,627
doing, which is extremely rare, so we rarely do try!.
才能这样做。这种情况很少见,我们很少会用 try!
87
00:04:22,696 --> 00:04:27,365
But a better one if you don't care about the error is try?.
如果你不关心它抛出的错误是什么,一个更好的方法是用 try?
88
00:04:27,434 --> 00:04:32,370
So try?, means please try this and if it throws, don't crash,
try? 意味着请尝试调用它,如果它抛出了错误,不要崩溃
89
00:04:32,439 --> 00:04:36,441
but just ignore the fact that it threw. So
但也无视它抛出的错误
90
00:04:36,510 --> 00:04:37,509
this is kind of like try and
这就有点像尝试调用
91
00:04:37,578 --> 00:04:40,445
ignore. Now the interesting thing is, you might be calling
并无视错误。而有趣的是,你可能会调用
92
00:04:40,513 --> 00:04:44,382
a function that returns a value. An int that can throw.
一个有返回值的函数,比如说返回一个整形,而这个函数还会抛出错误
93
00:04:44,451 --> 00:04:47,184
So here I've got my error prone function that returns
这里我有这个函数,它会返回一个整形
94
00:04:47,253 --> 00:04:52,089
an int, okay, and so what if I wanna try it with try?. Well,
那么如果我在这里使用 try? 来调用它
95
00:04:52,158 --> 00:04:55,560
if it succeeds, I need that int back. But if it fails,
如果没有错误,我要取得那个整形的值,但如果它失败了
96
00:04:55,629 --> 00:05:00,198
I can't get the int back. So what happens when you do try?,
我无法取得那个整形的值,那么当你用 try? 的时候会发生什么
97
00:05:00,266 --> 00:05:04,102
it changes the return value essentially, of the function
它实际上改变了这个函数的返回值类型
98
00:05:04,170 --> 00:05:07,405
to be an optional version of that value. So
改成了这个函数的返回值类型的可选类型
99
00:05:07,474 --> 00:05:09,974
if you have an error prone function returns an int and
那么如果你有这里这个返回整形的函数
100
00:05:10,043 --> 00:05:13,144
you try? it, and you let it equal something, you know,
并且用 try? 调用它,接着赋值给某个变量
101
00:05:13,213 --> 00:05:16,347
let x equal that. This x now becomes an optional int,
比如说 let x = 那个函数,那么 x 的类型就变成了可选的整形
102
00:05:16,416 --> 00:05:19,117
because if it throws, it's gonna give you
因为如果那个函数抛出了错误
103
00:05:19,185 --> 00:05:21,786
nil. If it doesn't throw, you'll get the normal x value
它会返回 nil 如果它没有抛出错误,x 就是正常
104
00:05:21,855 --> 00:05:25,756
that error prone function that returns an int, returns. Okay?
的那个函数的整形返回值
105
00:05:25,825 --> 00:05:28,426
So that's error handling. There's not a lot of methods
那么这就是错误处理,在 iOS 中并不是有
106
00:05:28,495 --> 00:05:31,596
that throw in iOS there, in there occasionally. You know,
许多的函数会抛出错误,有时
107
00:05:31,665 --> 00:05:33,965
you might have a typical app, maybe you have three or
你可能会有个特定的程序中有一些这样的抛出
108
00:05:34,034 --> 00:05:36,601
four of them, somewhere. They're fairly rare but
错误的函数。它们比较少见
109
00:05:36,670 --> 00:05:39,137
you got to know how to handle them. So these are the ways to
但你也要知道该如何处理它们,就是通过我们刚刚讲到的方法
110
00:05:39,205 --> 00:05:43,708
handle them. All right, I wanna circle back now to Any.
好的,那么让我们现在回去讲 Any
111
00:05:43,777 --> 00:05:45,309
This type Any that we saw with
这个 Any 类型
112
00:05:45,378 --> 00:05:49,113
NSAttributedString dictionary. There's another one called any
我们曾在 NSAttributedString dictionary 中见过。还有一个类型叫做
113
00:05:49,182 --> 00:05:52,550
object which is exact the same as Any, it's just for classes
AnyObject,它和 Any 是完全一样的,只是它只能用于
114
00:05:52,619 --> 00:05:55,820
only, and the object is the any of classes only. And
类,AnyObject 是 Any 的类的表达
115
00:05:55,889 --> 00:05:58,856
I told you that Any means, you don't know what type it is,
我讲过,Any 意味着你不知道这个类型是什么
116
00:05:58,925 --> 00:06:02,360
it could be any type. And we also know that that's not
它可以是任意的类型,并且我们也知道
117
00:06:02,428 --> 00:06:06,597
very Swifty, and cuz Swift is strongly tight. So Any and
它不是很符合 Swift 的风格,因为 Swift 是一个强类型语言
118
00:06:06,666 --> 00:06:09,601
AnyObject are in there for compatible with Objective-C.
AnyObject 只是为了能与 Objective-C 兼容
119
00:06:09,670 --> 00:06:12,870
Objective-C had a very important type called ID which
Objective-C 中有一个非常重要的类型叫做 ID
120
00:06:12,939 --> 00:06:16,775
was essentially any and it was built in to all of the APIs.
它本质上就是 Any,并且它被写入了所有的 API 中
121
00:06:16,843 --> 00:06:19,777
So when Swift came along and tried to be strongly typed,
所以当 Swift 要成为强类型语言
122
00:06:19,846 --> 00:06:22,213
it had to have this one concession. So
它必须要做这个让步
123
00:06:22,281 --> 00:06:25,483
we don't use as I've said, any in our own code, it's for
我们不会再我们自己的代码中用到 Any
124
00:06:25,552 --> 00:06:29,554
backwards compatibility. So variables of type any could
它只是用来向后兼容的。Any 类型的变量可以
125
00:06:29,622 --> 00:06:34,960
hold any type. Structs, enums, classes, anything.
保存任何类型,结构体,枚举类型,类,任何类型都可以
126
00:06:35,028 --> 00:06:39,096
And the problem though is, you can't send any messages to
而问题是你不能向 Any 类型的对象
127
00:06:39,165 --> 00:06:42,600
something of type Any, because you don't, in your code,
传递信息,因为在你的代码中,你不知道它具体
128
00:06:42,669 --> 00:06:45,537
know what it is. Okay? Now, Swift, under the covers,
是什么类型,Swift 知道
129
00:06:45,606 --> 00:06:48,172
might know what it is, but since you've typed it Any,
它是什么类型的,但因为你将它设置为 Any 类型
130
00:06:48,241 --> 00:06:51,042
it's assuming you don't want to send any messages to it
Swift 会假设你不想向它传递任何消息
131
00:06:51,110 --> 00:06:54,712
that you don't know what it is. So, how do we
因为你不知道它是什么。那么,我们如何
132
00:06:54,781 --> 00:06:57,381
deal with that case in Swift where we got the strongly type
在 Swift 这种强类型语言中处理这种
133
00:06:57,450 --> 00:06:59,250
language, we can't send a message to Any. Well,
情况呢,我们现在无法向 Any 传递信息
134
00:06:59,318 --> 00:07:03,287
we got to convert it. Now, let's talk about where you're
实际上,我们需要转变(convert)它,我们先讲讲你们会在哪里
135
00:07:03,356 --> 00:07:06,391
gonna see it, you already saw it in NSAttributedString case,
碰到 Any,你们已经在 NSAttibutedString 中见过 Any
136
00:07:06,460 --> 00:07:08,159
right? Well, we have that dictionary.
我们有那个字典类型
137
00:07:08,228 --> 00:07:11,796
Another place you will see it is arguments to methods. So
另外一个你们会用到 Any 的地方是在函数的参数
138
00:07:11,864 --> 00:07:13,364
here is a method called prepare for
这有个函数叫做 prepare(for segue)
139
00:07:13,433 --> 00:07:16,667
segue. It's a UIView controller method, right?
它是一个在 UIViewController 中的函数
140
00:07:16,736 --> 00:07:18,069
You all know what a UIView controller is?
大家都知道 UIViewController 是什么吧
141
00:07:18,137 --> 00:07:20,705
We made one for concentration. And
我们在 Concentration 中写了一个
142
00:07:20,774 --> 00:07:24,709
I talked about when we do MVCs and we have multiple MVCs, and
我们在我们将多 MVC 的时候讲到当我们有多个 MVC
143
00:07:24,778 --> 00:07:28,246
they own a whole screen. Well, we sometimes transition from
并且它们各自拥有自己的屏幕的时候,我们有时需要从一个
144
00:07:28,315 --> 00:07:31,682
one MVC together, to another. And this prepare for segue,
MVC 跳到另一个 MVC,而这个 prepare(for segue)
145
00:07:31,751 --> 00:07:34,785
a segue is a transition from one MVC to the other, this
一个 segue 就是从一个 MVC 到另一个 MVC 的跳转
146
00:07:34,854 --> 00:07:38,490
gets called in a view control when transition happens. Well,
当跳转发生的时候,这个在对应的 ViewController 的 prepare 函数就会被调用
147
00:07:38,558 --> 00:07:41,993
one of the arguments to it there at the end is sender of
而它的最后的那个参数就是 Any? 类型的 sender
148
00:07:42,062 --> 00:07:46,564
type Any?. Okay, an optional Any. And that's basically
一个可选类型的 Any,它代表的就是
149
00:07:46,633 --> 00:07:51,269
what button cause this MVC transfer to a new MVC so.
使得从一个 MVC 到另一个 MVC 跳转发生的那个按钮
150
00:07:51,338 --> 00:07:54,072
So it could well be a button that, that sender is but
那么这个 sender 可以是一个按钮
151
00:07:54,141 --> 00:07:56,608
it can also happen if you click on a row in a table
但是,这个跳转也可能在你点击一个 UITableView 的一行的时候
152
00:07:56,676 --> 00:08:00,445
view. So that's not a button, that's a table view. Cell,
发生,这种情况下,sender 就不是按钮了,它应该是一个 UITableViewCell
153
00:08:00,513 --> 00:08:02,980
okay, or it could happen from something else.
这个跳转也可能从其他地方发生
154
00:08:03,049 --> 00:08:06,050
It could even happen by code, in which case this is a nil.
甚至可能是由代码直接命令执行的,在这种情况下 sender 应该是 nil
155
00:08:06,119 --> 00:08:09,220
So that's why you need Any right there, because you're
因此你在这里要用到 Any,因为你不确定
156
00:08:09,288 --> 00:08:12,057
not sure whether it was a button or a table view cell or
是一个 UIButton 还是 UITableViewCell 还是
157
00:08:12,125 --> 00:08:15,025
something else that caused this thing to happen. So
其他什么让这个跳转发生的
158
00:08:15,094 --> 00:08:19,097
you'll see it as arguments, a case very rarely to a function
所以你有时会看到一个函数的参数
159
00:08:19,166 --> 00:08:23,201
like this where you can kinda pass anything in there,. But
就像这样,我们可以向它传递任意的参数
160
00:08:23,270 --> 00:08:27,439
how are we gonna use this Any stuff? Okay, let's say
但是我们要如何使用这个 Any 类型的变量呢
161
00:08:27,507 --> 00:08:30,241
a button was passed on your table, how do I know what it
比如说一个按钮或者一个列表视图被传来进来
162
00:08:30,309 --> 00:08:33,310
is and talk to it, and all that when it's this Any thing.
我该如何知道它是什么并且向它传递信息呢
163
00:08:33,379 --> 00:08:37,816
Okay, before I show you how to do it, of course don't use Any
在向你们展示该怎么做之前,请不要在这门课中使用 Any
164
00:08:37,884 --> 00:08:41,319
in this course except for to do backwards compatible call
除非你要做向后兼容或者调用
165
00:08:41,388 --> 00:08:44,823
APIs. You don't have your own data structures would not be
API,你在你自己的数据类型中
166
00:08:44,892 --> 00:08:47,492
use Any. Some people try to use Any when
不要使用 Any,有的人在不知道该如何设计
167
00:08:47,561 --> 00:08:49,561
they basically don't know how to design a data structure,
数据类型的时候就简单地使用 Any
168
00:08:49,630 --> 00:08:51,395
and they're like, I'll just make this an Any,
他们就想,我直接把这个变量设为 Any就好了
169
00:08:51,464 --> 00:08:52,396
an array of Any and
一个 Any 类型的数组
170
00:08:52,465 --> 00:08:53,965
I'll just start throwing random things in there.
这样就可以向数组中存任何东西了
171
00:08:54,034 --> 00:08:57,535
No, we don't do that, okay, that's not, Swift. All right,
我们不会这么做,这不是 Swift 的风格
172
00:08:57,604 --> 00:09:01,039
so now how do I use Any. I have to convert it to a type
那么该如何使用 Any 呢,我必须要将它转变为一个
173
00:09:01,107 --> 00:09:04,609
that I do know, since I can't send any messages or vars,
我认识的类型,因为我不能向它传递任何函数或者变量
174
00:09:04,678 --> 00:09:07,011
I have to convert it. And we convert it,
我必须要转变它。而我们通过
175
00:09:07,080 --> 00:09:09,847
with a special keyword and Swift called as,
一个 Swift 中的特殊的关键字,叫做 as 来转变它
176
00:09:09,916 --> 00:09:14,385
as question mark. And what as does, is it just tries to
as? 它做的就是尝试转变那个 Any 类型变量
177
00:09:14,453 --> 00:09:18,056
convert that any to the type you specify and if it can't,
为你指定的那个类型,如果它不能转变的话
178
00:09:18,124 --> 00:09:21,326
it returns a nil. That's why it's as question mark.
就返回 nil,因此它是 as 后面接问号
179
00:09:21,394 --> 00:09:23,894
And it's as simple as that. So here's an example,
就这么简单,这有一个例子
180
00:09:23,963 --> 00:09:25,262
it's best learn by example here.
我们最后通过例子来学习
181
00:09:25,331 --> 00:09:29,934
Let's say, I have a var called unknown, which of type Any, so
加入我有一个叫做 unknown 的变量,它是 Any 类型的
182
00:09:30,003 --> 00:09:32,237
I don't know what's in it. It could be anything in there,
我不知道它里面装的是什么,它可以装任何东西
183
00:09:32,305 --> 00:09:36,941
and I think that that thing in unknown might be of type,
而我觉得 unknown 的类型可能是
184
00:09:37,009 --> 00:09:40,244
MyType. I'm not sure but I think it might be MyType.
MyType,我不确定,我我觉得它有可能是 MyType
185
00:09:40,313 --> 00:09:44,982
So I'm gonna say if I can let foo, which is a new variable,
那么我只用写如果我可以 let foo,foo 是一个新的变量
186
00:09:45,051 --> 00:09:50,055
equal unknown as MyType. Then inside there,
let foo = unknown as? MyType 那么在那里
187
00:09:50,123 --> 00:09:53,391
I can send messages to foo that MyType understands,
我可以向 foo 传递 MyType 可以理解的信息
188
00:09:53,460 --> 00:09:56,460
right? So I've just converted unknown into
所以我就是将unknown 转变为了一个新的
189
00:09:56,529 --> 00:10:00,565
a new variable of type MyType, if possible by using as.
MyType 类型的变量,通过使用 as 关键字
190
00:10:00,634 --> 00:10:02,567
And you can see this is nice, it reads like English.
你们可以发现这很棒,读起来就像英语一样
191
00:10:02,636 --> 00:10:05,703
If I can let foo equal unknown as MyType,
如果我可以让 foo 等于 MyType 类型的 unknown
192
00:10:05,772 --> 00:10:09,674
then I'm going to use it as MyType. So that's it,
那么我就接着以 MyType 类型来使用它
193
00:10:09,743 --> 00:10:12,844
it's very simple, that's how we access Any. And
就是这么简单,这就是我们使用 Any 的方法
194
00:10:12,912 --> 00:10:15,413
if it wasn't, if unknown was of some other type and
如果它不是,如果 unknown 是其他什么类型
195
00:10:15,481 --> 00:10:17,381
couldn't be interpreted as MyType,
而不能被转变为 MyType
196
00:10:17,450 --> 00:10:20,217
then this the curly braces, that stuff doesn't happen.
那么这段大括号中的代码就不会被执行
197
00:10:20,286 --> 00:10:22,253
You could even say else, and something else, and
你甚至可以用 else,那么
198
00:10:22,322 --> 00:10:24,522
something else would happen, that would be fine too.
else 中的代码就会被执行
199
00:10:24,591 --> 00:10:27,258
Now this casting of As is not just for
而这个 as 所做的转变
200
00:10:27,327 --> 00:10:31,295
Any, we can also cast other things. Why, why else would we
不仅适用于 Any,它也可以用来做其他类型的转变,为什么