├── .gitignore ├── Blog-Perspective.png ├── Posts ├── Focus │ ├── AFNetworking │ │ ├── 1.png │ │ ├── 2.png │ │ ├── README.md │ │ └── afnetworking-logo.png │ ├── Category_in_Obj-C │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── Category_in_Obj-C │ │ │ ├── Category_in_Obj-C.xcodeproj │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata │ │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcshareddata │ │ │ │ │ └── xcschemes │ │ │ │ │ └── Category_in_Obj-C.xcscheme │ │ │ └── Category_in_Obj-C │ │ │ │ ├── Person+Category.h │ │ │ │ ├── Person+Category.m │ │ │ │ ├── Person+Extension.h │ │ │ │ ├── Person+Inner.h │ │ │ │ ├── Person+Life.cpp │ │ │ │ ├── Person+Life.h │ │ │ │ ├── Person+Life.m │ │ │ │ ├── Person+Work.h │ │ │ │ ├── Person+Work.m │ │ │ │ ├── Person.h │ │ │ │ ├── Person.m │ │ │ │ ├── main.m │ │ │ │ ├── xnu-memcpy.c │ │ │ │ └── xnu-memcpy.h │ │ └── README.md │ ├── KVC_in_iOS │ │ ├── 1.png │ │ └── README.md │ ├── KVO_in_iOS │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ └── README.md │ ├── Link_Map_File_in_Xcode │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ └── README.md │ ├── NSObject_in_iOS │ │ ├── 1.png │ │ └── README.md │ ├── Objects_in_Obj-C │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ └── README.md │ ├── Swift_Autoclosure │ │ ├── 1.png │ │ ├── README.md │ │ └── Swift_Autoclosure_Demo.playground │ │ │ └── playground.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ └── kingcos.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── Swift_Properties │ │ └── README.md │ ├── Swift_Selector │ │ ├── README.md │ │ └── title.png │ ├── UIViewController_Life_Cycle │ │ ├── 1.png │ │ └── README.md │ ├── alloc_init_vs_new_in_Obj-C │ │ └── README.md │ ├── dyld_shared_cache │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.jpeg │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ └── README.md │ └── iOS_App_Start_up │ │ ├── 1.png │ │ └── README.md ├── Practice │ ├── +initialize_in_iOS │ │ ├── Initialize_Demo │ │ │ ├── Initialize_Demo.xcodeproj │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata │ │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcshareddata │ │ │ │ │ └── xcschemes │ │ │ │ │ └── Initialize_Demo.xcscheme │ │ │ └── Initialize_Demo │ │ │ │ ├── Person+Life.h │ │ │ │ ├── Person+Life.m │ │ │ │ ├── Person+Work.h │ │ │ │ ├── Person+Work.m │ │ │ │ ├── Person.h │ │ │ │ ├── Person.m │ │ │ │ ├── Programmer.h │ │ │ │ ├── Programmer.m │ │ │ │ ├── Student+School.h │ │ │ │ ├── Student+School.m │ │ │ │ ├── Student.h │ │ │ │ ├── Student.m │ │ │ │ └── main.m │ │ └── README.md │ ├── +load_in_iOS │ │ ├── Load_Obj-C_Demo │ │ │ ├── Load_Obj-C_Demo.xcodeproj │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata │ │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcshareddata │ │ │ │ │ └── xcschemes │ │ │ │ │ └── Load_Obj-C_Demo.xcscheme │ │ │ └── Load_Obj-C_Demo │ │ │ │ ├── Person+Life.h │ │ │ │ ├── Person+Life.m │ │ │ │ ├── Person+Work.h │ │ │ │ ├── Person+Work.m │ │ │ │ ├── Person.h │ │ │ │ ├── Person.m │ │ │ │ ├── Student+School.h │ │ │ │ ├── Student+School.m │ │ │ │ ├── Student.h │ │ │ │ ├── Student.m │ │ │ │ └── main.m │ │ ├── Load_Obj-C_iOS_Demo │ │ │ ├── Load_Obj-C_iOS_Demo.xcodeproj │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata │ │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcshareddata │ │ │ │ │ └── xcschemes │ │ │ │ │ └── Load_Obj-C_iOS_Demo.xcscheme │ │ │ └── Load_Obj-C_iOS_Demo │ │ │ │ ├── AppDelegate.h │ │ │ │ ├── AppDelegate.m │ │ │ │ ├── Assets.xcassets │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ │ ├── Base.lproj │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ │ │ ├── Info.plist │ │ │ │ ├── ViewController.h │ │ │ │ ├── ViewController.m │ │ │ │ └── main.m │ │ └── README.md │ ├── CI_Practice_in_iOS │ │ └── 1 │ │ │ ├── 1.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ ├── 4.png │ │ │ ├── 5.png │ │ │ ├── 6.png │ │ │ ├── README.md │ │ │ └── image.png │ ├── Docker_for_Hadoop │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 2.png │ │ ├── 20.png │ │ ├── 21.png │ │ ├── 22.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ ├── 9.png │ │ └── README.md │ ├── Locks_in_iOS │ │ └── README.md │ ├── Multithread_Techs_in_iOS │ │ ├── 1-pthreads │ │ │ └── README.md │ │ ├── 2-NSThread │ │ │ └── README.md │ │ ├── iOS_Multithread_Tech_Demo │ │ │ ├── iOS_Multithread_Tech_Demo.xcodeproj │ │ │ │ ├── project.pbxproj │ │ │ │ └── project.xcworkspace │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── iOS_Multithread_Tech_Demo │ │ │ │ ├── POSIXThreadManager.h │ │ │ │ ├── POSIXThreadManager.m │ │ │ │ ├── iOS_Multithread_Tech_Demo-Bridging-Header.h │ │ │ │ └── main.m │ │ └── iOS_Multithread_Tech_Demo_Swift │ │ │ ├── iOS_Multithread_Tech_Demo_Swift.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── iOS_Multithread_Tech_Demo_Swift │ │ │ ├── PThreadsManager.swift │ │ │ └── main.swift │ ├── NSCoding_in_iOS │ │ └── README.md │ ├── NumPy_Basics │ │ └── README.ipynb │ ├── Type_Introspection_and_Reflection │ │ ├── README.md │ │ └── Type_Introspection_and_Reflection │ │ │ ├── Type_Introspection_and_Reflection.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── Type_Introspection_and_Reflection.xcscheme │ │ │ └── Type_Introspection_and_Reflection │ │ │ ├── Obj-C │ │ │ ├── Person.h │ │ │ ├── Person.m │ │ │ └── Type_Introspection_and_Reflection-Bridging-Header.h │ │ │ ├── Swift │ │ │ ├── Animal.swift │ │ │ └── Computer.swift │ │ │ └── main.swift │ ├── Weakly_Collections │ │ ├── README.md │ │ └── Weekly_Collections_Demo.playground │ │ │ ├── Contents.swift │ │ │ ├── contents.xcplayground │ │ │ └── playground.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcuserdata │ │ │ └── kingcos.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── ivar_Access_Control_in_Obj-C │ │ ├── 1.png │ │ └── README.md ├── Promotion │ ├── CMU_INI_Kobe │ │ ├── 2-1_How_To_Apply │ │ │ └── README.md │ │ └── README.md │ └── Machine_Learning │ │ ├── ML.png │ │ ├── README.md │ │ └── Road_Map │ │ ├── 1-Math-Linear_Algebra │ │ ├── 1.LHY_LA.ipynb │ │ ├── 2.LYB_LA.ipynb │ │ └── Vector │ │ │ └── Vector │ │ │ ├── Matrix.swift │ │ │ └── Vector.swift │ │ └── 2-Machine-Learning │ │ └── 1-kNN.ipynb ├── Studying │ ├── Effective_Objective-C_2.0 │ │ ├── 1 │ │ │ └── README.md │ │ ├── Effective_Obj-C_Demo │ │ │ ├── Effective_Obj-C_Demo.xcodeproj │ │ │ │ ├── project.pbxproj │ │ │ │ └── project.xcworkspace │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── Effective_Obj-C_Demo │ │ │ │ ├── Computer.h │ │ │ │ ├── Computer.m │ │ │ │ ├── Mac.h │ │ │ │ ├── Mac.m │ │ │ │ ├── MacPro.h │ │ │ │ ├── MacPro.m │ │ │ │ ├── main.m │ │ │ │ └── objc-header.h │ │ └── README.md │ ├── ICS_15-213 │ │ ├── 01-overview │ │ │ └── README.md │ │ ├── 02-bits_bytes_integer_i │ │ │ └── README.md │ │ └── README.md │ ├── MacOSX_and_iOS_Internals │ │ └── README.md │ ├── Programming_from_the_Ground_Up │ │ └── README.md │ └── WWDC │ │ └── 2017 │ │ ├── 102 │ │ ├── README.md │ │ └── img │ │ │ ├── 1.png │ │ │ └── 2.png │ │ ├── 819 │ │ └── README.md │ │ ├── 822 │ │ └── README.md │ │ └── 823 │ │ └── README.md ├── Thought │ ├── 180625 │ │ └── README.md │ ├── 180706 │ │ └── README.md │ ├── 180715 │ │ └── README.md │ ├── 180727 │ │ └── README.md │ ├── 180805 │ │ └── README.md │ ├── 181210 │ │ ├── 1.png │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ └── README.md │ └── 190120 │ │ └── README.md ├── Tips │ ├── AirPlay_on_Pi │ │ ├── 1.png │ │ ├── 2.jpg │ │ └── README.md │ ├── JDK_Multiple_Versions │ │ ├── 1.png │ │ ├── 2.png │ │ └── README.md │ ├── Jenkins_by_Homebrew │ │ ├── 1.png │ │ └── README.md │ ├── Livestreaming_on_macOS │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ └── README.md │ ├── MySQL_by_Homebrew │ │ └── README.md │ ├── Obj-C_to_Cpp │ │ ├── 1.png │ │ └── README.md │ ├── Override_and_Overload_in_Obj-C │ │ └── README.md │ ├── Supervisor │ │ └── README.md │ ├── Swift_GYB │ │ ├── 1.png │ │ └── README.md │ ├── Xcode_10_beta │ │ └── README.md │ ├── iOS_Dev_Issue_List │ │ └── README.md │ └── usbmuxd │ │ └── README.md └── Translation │ ├── About_the_App_Launch_Sequence │ ├── 1.png │ └── README.md │ ├── Designating_Nullability_in_Objective-C_APIs │ └── README.md │ ├── Performing_One-Time_Setup_for_Your_App │ └── README.md │ ├── URL_Loading_System │ ├── 1.png │ └── README.md │ └── Uncovering_SourceKit │ ├── 1.jpeg │ ├── 2.jpeg │ ├── 3.jpeg │ ├── 4.jpeg │ ├── 5.jpeg │ ├── 6.jpeg │ ├── 7.jpeg │ ├── 8.png │ └── README.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | **/xcuserdata/* -------------------------------------------------------------------------------- /Blog-Perspective.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Blog-Perspective.png -------------------------------------------------------------------------------- /Posts/Focus/AFNetworking/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/AFNetworking/1.png -------------------------------------------------------------------------------- /Posts/Focus/AFNetworking/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/AFNetworking/2.png -------------------------------------------------------------------------------- /Posts/Focus/AFNetworking/afnetworking-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/AFNetworking/afnetworking-logo.png -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Category_in_Obj-C/1.png -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Category_in_Obj-C/2.png -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Category_in_Obj-C/3.png -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C.xcodeproj/xcshareddata/xcschemes/Category_in_Obj-C.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/Person+Category.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Category.h 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/16. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person (Category) 14 | 15 | - (void)eat; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/Person+Category.m: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Category.m 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/16. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person+Category.h" 10 | 11 | @implementation Person (Category) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/Person+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Extension.h 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/16. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person () 14 | 15 | - (void)drink; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/Person+Inner.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Inner.h 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/14. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person () 14 | 15 | - (void)bar; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/Person+Life.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Life.h 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/13. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | /** 14 | LifeProtocol 15 | */ 16 | @protocol LifeProtocol 17 | - (void)eat; 18 | @end 19 | 20 | /** 21 | Person+Life 22 | */ 23 | @interface Person (Life) 24 | 25 | @property (nonatomic, copy) NSString *name; 26 | 27 | // Instance method 28 | - (void)run; 29 | 30 | // Class method 31 | + (void)foo; 32 | 33 | // Protocol method 34 | - (void)eat; 35 | 36 | - (void)smile; 37 | 38 | @end 39 | 40 | NS_ASSUME_NONNULL_END 41 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/Person+Life.m: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Life.m 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/13. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person+Life.h" 10 | 11 | @implementation Person (Life) 12 | 13 | + (void)load { 14 | 15 | } 16 | 17 | // Instance method 18 | - (void)run { 19 | NSLog(@"%s", __func__); 20 | } 21 | 22 | // Class method 23 | + (void)foo { 24 | NSLog(@"%s", __func__); 25 | } 26 | 27 | // Protocol method 28 | - (void)eat { 29 | NSLog(@"%s", __func__); 30 | } 31 | 32 | - (void)smile { 33 | NSLog(@"Person (Life) - %s", __func__); 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/Person+Work.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Work.h 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/13. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person (Work) 14 | 15 | - (void)smile; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/Person+Work.m: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Work.m 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/13. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person+Work.h" 10 | 11 | @implementation Person (Work) 12 | 13 | + (void)load { 14 | 15 | } 16 | 17 | - (void)smile { 18 | NSLog(@"Person (Work) - %s", __func__); 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/Person.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person.h 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/13. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person : NSObject 14 | 15 | - (void)smile; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/Person.m: -------------------------------------------------------------------------------- 1 | // 2 | // Person.m 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/13. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | #import "Person+Inner.h" 11 | 12 | @interface Person () { 13 | // 默认为 private 14 | int _age; 15 | @protected 16 | NSString *_name; 17 | } 18 | 19 | - (void)secret; 20 | 21 | @end 22 | 23 | @implementation Person 24 | 25 | - (void)eat { 26 | NSLog(@"%s", __func__); 27 | } 28 | 29 | - (void)drink { 30 | NSLog(@"%s", __func__); 31 | } 32 | 33 | + (void)load { 34 | 35 | } 36 | 37 | - (void)smile { 38 | NSLog(@"Person - %s", __func__); 39 | } 40 | 41 | - (void)bar { 42 | NSLog(@"Person - %s", __func__); 43 | } 44 | 45 | - (void)secret { 46 | NSLog(@"Person - %s", __func__); 47 | } 48 | 49 | @end 50 | 51 | @interface Student : Person 52 | 53 | @end 54 | 55 | @implementation Student 56 | 57 | - (void)bar { 58 | // NSLog(@"%d", _age); 59 | NSLog(@"%@", _name); 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/13. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "Person+Life.h" 12 | #import "Person+Work.h" 13 | 14 | #import "Person+Category.h" 15 | #import "Person+Extension.h" 16 | 17 | #import "xnu-memcpy.h" 18 | 19 | // Class Extension 20 | @interface Person () 21 | - (void)secret; 22 | @end 23 | 24 | int main(int argc, const char * argv[]) { 25 | @autoreleasepool { 26 | // Category: 27 | Person *p = [[Person alloc] init]; 28 | [p smile]; 29 | 30 | [p eat]; 31 | [p drink]; 32 | 33 | // memmove 34 | // b -> a 35 | int a = 10; 36 | int b = 20; 37 | NSLog(@"Before: a: %d, b: %d", a, b); 38 | // _libkernel_memmove(void *dst0, const void *src0, size_t length) 39 | _libkernel_memmove(&a, &b, sizeof(int)); 40 | // memmove(&a, &b, sizeof(int)); 41 | // memcpy(&a, &b, sizeof(int)); 42 | NSLog(@"After: a: %d, b: %d", a, b); 43 | 44 | // c -> d 45 | int c = 30; 46 | int d = 40; 47 | NSLog(@"Before: c: %d, d: %d", c, d); 48 | // _libkernel_memmove2 是个简化版本的 _libkernel_memmove 49 | _libkernel_memmove2(&d, &c, sizeof(int)); 50 | NSLog(@"After: c: %d, d: %d", c, d); 51 | 52 | // e[0, 1] -> e[1, 2] 53 | int e[5] = {1, 2, 3}; 54 | NSLog(@"Before: e[0]: %d, e[1]: %d, e[2]: %d, e[3]: %d, e[4]: %d", e[0], e[1], e[2], e[3], e[4]); 55 | _libkernel_memmove3(&e[2], &e[0], sizeof(int) * 3); 56 | NSLog(@"After: e[0]: %d, e[1]: %d, e[2]: %d, e[3]: %d, e[4]: %d", e[0], e[1], e[2], e[3], e[4]); 57 | 58 | // f[0, 1] -> f[1, 2] 59 | int f[5] = {1, 2, 3}; 60 | NSLog(@"Before: f[0]: %d, f[1]: %d, f[2]: %d, f[3]: %d, f[4]: %d", f[0], f[1], f[2], f[3], f[4]); 61 | v_memcpy(&f[2], &f[0], sizeof(int) * 3); 62 | NSLog(@"After: f[0]: %d, f[1]: %d, f[2]: %d, f[3]: %d, f[4]: %d", f[0], f[1], f[2], f[3], f[4]); 63 | } 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /Posts/Focus/Category_in_Obj-C/Category_in_Obj-C/Category_in_Obj-C/xnu-memcpy.h: -------------------------------------------------------------------------------- 1 | // 2 | // xnu-memcpy.h 3 | // Category_in_Obj-C 4 | // 5 | // Created by kingcos on 2019/4/14. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #ifndef xnu_memcpy_h 10 | #define xnu_memcpy_h 11 | 12 | #include 13 | 14 | void * _libkernel_memmove(void *dst0, const void *src0, size_t length); 15 | void _libkernel_memmove2(void *dst0, void *src0, size_t length); 16 | void _libkernel_memmove3(void *dst0, void *src0, size_t length); 17 | 18 | void * v_memcpy(void * dest, const void * src, size_t n); 19 | 20 | #endif /* xnu_memcpy_h */ 21 | -------------------------------------------------------------------------------- /Posts/Focus/KVC_in_iOS/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/KVC_in_iOS/1.png -------------------------------------------------------------------------------- /Posts/Focus/KVO_in_iOS/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/KVO_in_iOS/1.png -------------------------------------------------------------------------------- /Posts/Focus/KVO_in_iOS/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/KVO_in_iOS/2.png -------------------------------------------------------------------------------- /Posts/Focus/KVO_in_iOS/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/KVO_in_iOS/3.png -------------------------------------------------------------------------------- /Posts/Focus/KVO_in_iOS/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/KVO_in_iOS/4.png -------------------------------------------------------------------------------- /Posts/Focus/KVO_in_iOS/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/KVO_in_iOS/5.png -------------------------------------------------------------------------------- /Posts/Focus/KVO_in_iOS/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/KVO_in_iOS/6.png -------------------------------------------------------------------------------- /Posts/Focus/Link_Map_File_in_Xcode/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Link_Map_File_in_Xcode/1.png -------------------------------------------------------------------------------- /Posts/Focus/Link_Map_File_in_Xcode/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Link_Map_File_in_Xcode/2.png -------------------------------------------------------------------------------- /Posts/Focus/Link_Map_File_in_Xcode/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Link_Map_File_in_Xcode/3.png -------------------------------------------------------------------------------- /Posts/Focus/NSObject_in_iOS/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/NSObject_in_iOS/1.png -------------------------------------------------------------------------------- /Posts/Focus/Objects_in_Obj-C/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Objects_in_Obj-C/1.png -------------------------------------------------------------------------------- /Posts/Focus/Objects_in_Obj-C/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Objects_in_Obj-C/2.png -------------------------------------------------------------------------------- /Posts/Focus/Objects_in_Obj-C/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Objects_in_Obj-C/3.png -------------------------------------------------------------------------------- /Posts/Focus/Swift_Autoclosure/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Swift_Autoclosure/1.png -------------------------------------------------------------------------------- /Posts/Focus/Swift_Autoclosure/Swift_Autoclosure_Demo.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Posts/Focus/Swift_Autoclosure/Swift_Autoclosure_Demo.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Posts/Focus/Swift_Autoclosure/Swift_Autoclosure_Demo.playground/playground.xcworkspace/xcuserdata/kingcos.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Swift_Autoclosure/Swift_Autoclosure_Demo.playground/playground.xcworkspace/xcuserdata/kingcos.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Posts/Focus/Swift_Selector/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/Swift_Selector/title.png -------------------------------------------------------------------------------- /Posts/Focus/UIViewController_Life_Cycle/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/UIViewController_Life_Cycle/1.png -------------------------------------------------------------------------------- /Posts/Focus/UIViewController_Life_Cycle/README.md: -------------------------------------------------------------------------------- 1 | # Focus - 探究 UIViewController 生命周期 2 | 3 | | Date | Notes | Swift | Xcode | 4 | |:-----:|:-----:|:-----:|:-----:| 5 | | 2017-03-10 | 首次提交 | 3.0 | 8.2.1 | 6 | 7 | ## 前言 8 | 9 | 对象的生命周期一直是开发者所需要关心的,教授 [CS193p](https://github.com/kingcos/CS193P_2017) 的老师 Paul 也详细的讲述了 UIViewController 的生命周期。为了记述这一过程,故作此文。由于 Xcode 提供了纯代码和 Storyboard(Xib 同理)两种布局 UI 的方式,因此初始化部分略有不同。 10 | 11 | 为了方便观察,我创建了一个 BaseViewController,继承自原本的 UIViewController,重写其中的生命周期方法,并让后续新的控制器继承自该控制器,以便观察。 12 | 13 | 本文对应的 Demo 可以在 [https://github.com/kingcos/UIViewController-UIView-LifecycleDemo](https://github.com/kingcos/UIViewController-UIView-LifecycleDemo) 查看、下载。 14 | 15 | ![Structure](1.png) 16 | 17 | ## Initialization 18 | 19 | ### Storyboard 20 | 21 | > **OUTPUT:** 22 | init(coder:) 23 | awakeFromNib() 24 | 25 | #### init(coder:) 26 | 27 | - 当使用 Storyboard 时,控制器的构造器为 `init(coder:)`。 28 | - 该构造器为必需构造器,如果重写其他构造器,则必须重写该构造器。 29 | - 该构造器为可失败构造器,即有可能构造失败,返回 nil。 30 | - 该方法来源自 NSCoding 协议,而 UIViewController 遵从这一协议。 31 | - 该方法被调用意味着控制器有可能(并非一定)在未来会显示。 32 | - 在控制器生命周期中,该方法只会被调用一次。 33 | 34 | #### awakeFromNib() 35 | 36 | - 当使用 Storyboard 时,该方法会被调用。 37 | - 当调用该方法时,将保证所有的 outlet 和 action 连接已经完成。 38 | - 该方法内部必须调用父类该方法,虽然默认实现为空,但 UIKit 中许多类的该方法为非空。 39 | - 由于控制器中对象的初始化顺序不能确定,所以构造器中不应该向其他对象发送消息,而应当在 `awakeFromNib()` 中安全地发送。 40 | - 通常使用 `awakeFromNib()` 可以进行在设计时无法完成的必要额外设置。 41 | 42 | ### Code 43 | 44 | > **OUTPUT:** 45 | init(nibName:bundle:) - NibName: nil, Bundle: nil 46 | 47 | #### init(nibName:bundle:) 48 | 49 | - 当使用纯代码创建控制器,控制器的构造器为 `init(nibName:bundle:)`。 50 | - 虽然使用代码创建时调用了该构造器,但传入的参数均为 nil。 51 | 52 | --- 53 | 54 | > **OUTPUT:** 55 | loadView() 56 | viewDidLoad() 57 | viewWillAppear 58 | viewWillLayoutSubviews() - Optional((162.0, 308.0, 50.0, 50.0)) 59 | viewDidLayoutSubviews() - Optional((67.0, 269.0, 241.0, 129.0)) 60 | viewDidAppear 61 | viewWillDisappear 62 | viewDidDisappear 63 | deinit 64 | 65 | ## loadView() 66 | 67 | - `loadView()` 即加载控制器管理的 view。 68 | - 不能直接手动调用该方法;当 view 被请求却为 nil 时,该方法加载并创建 view。 69 | - 若控制器有关联的 Nib 文件,该方法会从 Nib 文件中加载 view;如果没有,则创建空白 UIView 对象。 70 | - 如果使用 Interface Builder 创建 view,则务必不要重写该方法。 71 | - 可以使用该方法手动创建视图,且需要将根视图分配为 view;自定义实现不应该再调用父类的该方法。 72 | - 执行其他初始化操作,建议放在 `viewDidLoad()` 中。 73 | 74 | ## viewDidLoad() 75 | 76 | - view 被加载到内存后调用 `viewDidLoad()`。 77 | - 重写该方法需要首先调用父类该方法。 78 | - 该方法中可以额外初始化控件,例如添加子控件,添加约束。 79 | - 该方法被调用意味着控制器有可能(并非一定)在未来会显示。 80 | - 在控制器生命周期中,该方法只会被调用一次。 81 | 82 | ## viewWillAppear(_:) 83 | 84 | - 该方法在控制器 view 即将添加到视图层次时以及展示 view 时所有动画配置前被调用。 85 | - 重写该方法需要首先调用父类该方法。 86 | - 该方法中可以进行操作即将显示的 view,例如改变状态栏的取向,类型。 87 | - 该方法被调用意味着控制器将一定会显示。 88 | - 在控制器生命周期中,该方法可能会被多次调用。 89 | 90 | > 注意: 91 | 如果控制器 A 被展示在另一个控制器 B 的 popover 中,那么控制器 B 不会调用该方法,直到控制器 A 清除。 92 | 93 | ## viewWillLayoutSubviews() 94 | 95 | - 该方法在通知控制器将要布局 view 的子控件时调用。 96 | - 每当视图的 bounds 改变,view 将调整其子控件位置。 97 | - 该方法可重写以在 view 布局子控件前做出改变。 98 | - 该方法的默认实现为空。 99 | - 该方法调用时,AutoLayout 未起作用。 100 | - 在控制器生命周期中,该方法可能会被多次调用。 101 | 102 | ## viewDidLayoutSubviews() 103 | 104 | - 该方法在通知控制器已经布局 view 的子控件时调用。 105 | - 该方法可重写以在 view 布局子控件后做出改变。 106 | - 该方法的默认实现为空。 107 | - 该方法调用时,AutoLayout 已经完成。 108 | - 在控制器生命周期中,该方法可能会被多次调用。 109 | 110 | ## viewDidAppear(_:) 111 | 112 | - 该方法在控制器 view 已经添加到视图层次时被调用。 113 | - 重写该方法需要首先调用父类该方法。 114 | - 该方法可重写以进行有关正在展示的视图操作。 115 | - 在控制器生命周期中,该方法可能会被多次调用。 116 | 117 | ## viewWillDisappear(_:) 118 | 119 | - 该方法在控制器 view 将要从视图层次移除时被调用。 120 | - 类似 `viewWillAppear(_:)`。 121 | - 该方法可重写以提交变更,取消视图第一响应者状态。 122 | 123 | ## viewDidDisappear(_:) 124 | 125 | - 该方法在控制器 view 已经从视图层次移除时被调用。 126 | - 类似 `viewDidAppear(_:)`。 127 | - 该方法可重写以清除或隐藏控件。 128 | 129 | ## didReceiveMemoryWarning() 130 | 131 | - 当内存预警时,该方法被调用。 132 | - 不能直接手动调用该方法。 133 | - 该方法可重写以释放资源、内存。 134 | 135 | ## deinit 136 | 137 | - 控制器销毁时(离开堆),调用该方法。 138 | 139 | ## Note 140 | 141 | ### Rotation 142 | 143 | > **OUTPUT:** 144 | willTransition(to:with:) 145 | viewWillLayoutSubviews() - Optional((67.5, 269.5, 240.0, 128.0)) 146 | viewDidLayoutSubviews() - Optional((213.5, 123.5, 240.0, 128.0)) 147 | viewWillLayoutSubviews() - Optional((213.5, 123.5, 240.0, 128.0)) 148 | viewDidLayoutSubviews() - Optional((213.5, 123.5, 240.0, 128.0)) 149 | viewWillLayoutSubviews() - Optional((213.5, 123.5, 240.0, 128.0)) 150 | viewDidLayoutSubviews() - Optional((213.5, 123.5, 240.0, 128.0)) 151 | 152 | - 当 view 转变,会调用 `willTransition(to:with:)` 方法。 153 | - 当屏幕旋转,view 的 bounds 改变,其内部的子控件也需要按照约束调整为新的位置,因此也调用了 `viewWillLayoutSubviews()` 和 `viewDidLayoutSubviews()`。 154 | 155 | ### Present & Dismiss 156 | 157 | > **OUTPUT:** 158 | viewWillDisappear 159 | viewDidDisappear 160 | viewDidDisappear 161 | viewWillAppear 162 | viewDidAppear 163 | 164 | - 当在一个控制器内 Present 新的控制器,原先的控制器并不会销毁,但会消失,因此调用了 `viewWillDisappear` 和 `viewDidDisappear` 方法。 165 | - 如果新的控制器 Dismiss,即清除自己,原先的控制器会再一次出现,因此调用了其中的 `viewWillAppear` 和 `viewDidAppear` 方法。 166 | 167 | ### 死循环 168 | 169 | ```Swift 170 | class LoopViewController: UIViewController { 171 | 172 | override func loadView() { 173 | print(#function) 174 | } 175 | 176 | override func viewDidLoad() { 177 | print(#function) 178 | let _ = view 179 | } 180 | 181 | } 182 | ``` 183 | 184 | > **OUTPUT:** 185 | loadView() 186 | viewDidLoad() 187 | loadView() 188 | viewDidLoad() 189 | loadView() 190 | viewDidLoad() 191 | loadView() 192 | viewDidLoad() 193 | loadView() 194 | 195 | - 若 `loadView()` 没有加载 view,`viewDidLoad()` 会一直调用 `loadView()` 加载 view,因此构成了死循环,程序即卡死。 196 | 197 | ## Reference 198 | 199 | - [CS193P_2017](https://github.com/kingcos/CS193P_2017) 200 | - [UIViewController 相关生命周期总结](http://amztion.com/2016/12/03/uiviewcontroller-lifecycle/) 201 | 202 | -------------------------------------------------------------------------------- /Posts/Focus/alloc_init_vs_new_in_Obj-C/README.md: -------------------------------------------------------------------------------- 1 | # Focus - Obj-C 中的 alloc init 与 new 2 | 3 | | Date | Notes | Source Code | 4 | |:-----:|:-----:|:-----:| 5 | | 2019- | 首次提交 | [objc4-750](https://opensource.apple.com/tarballs/objc4/) | 6 | 7 | ## What 8 | 9 | 以 `NSObject` 为例,通常使用 `[[NSObject alloc] init]`,或者 `[NSObject new]`,来创建一个新的实例(Instance)对象。在开发中,很多人都会混用这两个方式,分不清其中的区别,似乎只是后者写起来更加简单。那么它们的本质到底是否一致呢? 10 | 11 | ## Why 12 | 13 | ```objc 14 | // NSObject.h 15 | + (instancetype)alloc OBJC_SWIFT_UNAVAILABLE("use object initializers instead"); 16 | 17 | - (instancetype)init 18 | #if NS_ENFORCE_NSOBJECT_DESIGNATED_INITIALIZER 19 | NS_DESIGNATED_INITIALIZER 20 | #endif 21 | ; 22 | 23 | + (instancetype)new OBJC_SWIFT_UNAVAILABLE("use object initializers instead"); 24 | ``` 25 | 26 | 在 Xcode 中,我们只能看到系统库的头文件,而无法看到其中的实现。但我们可以了解到,`alloc` 和 `new` 都是类方法,而 `init` 是对象方法。在 Apple 开源的 objc4 中,我们就可以根据这些信息找到其实现: 27 | 28 | ```objc 29 | // NSObject.mm 30 | @implementation NSObject 31 | 32 | + (id)alloc { 33 | return _objc_rootAlloc(self); 34 | } 35 | 36 | // Base class implementation of +alloc. cls is not nil. 37 | // Calls [cls allocWithZone:nil]. 38 | id 39 | _objc_rootAlloc(Class cls) 40 | { 41 | return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/); 42 | } 43 | 44 | - (id)init { 45 | return _objc_rootInit(self); 46 | } 47 | 48 | + (id)new { 49 | return [callAlloc(self, false/*checkNil*/) init]; 50 | } 51 | 52 | @end 53 | ``` 54 | 55 | 通过源代码,我们就能清晰地看出来,`new` 中其实也调用了 `init`,即初始化是相同的。所以他们的本质区别就在分配内存阶段的 `callAlloc`,`alloc` 的 `allocWithZone` 参数为 `true`,而 `new` 中使用了默认的 `false` 参数。 56 | 57 | ```objc 58 | // Call [cls alloc] or [cls allocWithZone:nil], with appropriate 59 | // shortcutting optimizations. 60 | static ALWAYS_INLINE id 61 | callAlloc(Class cls, bool checkNil, bool allocWithZone=false) 62 | { 63 | if (slowpath(checkNil && !cls)) return nil; 64 | 65 | #if __OBJC2__ 66 | if (fastpath(!cls->ISA()->hasCustomAWZ())) { 67 | // No alloc/allocWithZone implementation. Go straight to the allocator. 68 | // fixme store hasCustomAWZ in the non-meta class and 69 | // add it to canAllocFast's summary 70 | if (fastpath(cls->canAllocFast())) { 71 | // No ctors, raw isa, etc. Go straight to the metal. 72 | bool dtor = cls->hasCxxDtor(); 73 | id obj = (id)calloc(1, cls->bits.fastInstanceSize()); 74 | if (slowpath(!obj)) return callBadAllocHandler(cls); 75 | obj->initInstanceIsa(cls, dtor); 76 | return obj; 77 | } 78 | else { 79 | // Has ctor or raw isa or something. Use the slower path. 80 | id obj = class_createInstance(cls, 0); 81 | if (slowpath(!obj)) return callBadAllocHandler(cls); 82 | return obj; 83 | } 84 | } 85 | #endif 86 | 87 | // No shortcuts available. 88 | if (allocWithZone) return [cls allocWithZone:nil]; 89 | return [cls alloc]; 90 | } 91 | ``` 92 | 93 | ## Reference 94 | 95 | - [objc4-750](https://opensource.apple.com/tarballs/objc4/) -------------------------------------------------------------------------------- /Posts/Focus/dyld_shared_cache/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/dyld_shared_cache/1.png -------------------------------------------------------------------------------- /Posts/Focus/dyld_shared_cache/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/dyld_shared_cache/2.png -------------------------------------------------------------------------------- /Posts/Focus/dyld_shared_cache/3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/dyld_shared_cache/3.jpeg -------------------------------------------------------------------------------- /Posts/Focus/dyld_shared_cache/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/dyld_shared_cache/4.png -------------------------------------------------------------------------------- /Posts/Focus/dyld_shared_cache/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/dyld_shared_cache/5.png -------------------------------------------------------------------------------- /Posts/Focus/dyld_shared_cache/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/dyld_shared_cache/6.png -------------------------------------------------------------------------------- /Posts/Focus/dyld_shared_cache/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/dyld_shared_cache/7.png -------------------------------------------------------------------------------- /Posts/Focus/dyld_shared_cache/README.md: -------------------------------------------------------------------------------- 1 | # Focus - 谈谈 iOS 中的 `dyld_shared_cache` 2 | 3 | | Date | Notes | Source Code | 4 | |:-----:|:-----:|:-----:| 5 | | 2018-10-14 | 首次提交 | [dyld-551.4](https://opensource.apple.com/source/dyld/dyld-551.4/) | 6 | | 2018-12-12 | 补充 `dyld_shared_cache` 路径来源 | [system_cmds-805.220.1](https://opensource.apple.com/source/system_cmds/system_cmds-805.220.1/) 7 | 8 | ## What 9 | 10 | iOS & macOS 作为操作系统,其中内置了许多系统库(Library)。`dyld_shared_cache`,即动态库共享缓存。自 iOS 3.1 后,所有系统动态库被集合成一个 `dyld_shared_cache` 文件,以提升性能。当然,macOS 也有 `dyld_shared_cache`,比较特别的是可以通过 `update_dyld_shared_cache` 更新。 11 | 12 | ![`man update_dyld_shared_cache`](1.png) 13 | 14 | ## How 15 | 16 | 为了研究 `dyld_shared_cache`,首先要找到其存在的路径。可以在 Apple 开源的 system_cmds 中 `dyld_shared_cache.c` 文件中发现,其分别存放在 macOS 和 iOS 中的路径。 17 | 18 | ![system_cmds](6.png) 19 | 20 | macOS 上的 `dyld_shared_cache` 和 iOS 不太相同,每种架构额外对应了一种 `.map` 文件。因为本文着重在于 iOS,读者想要了解 macOS 相关可以在 system_cmds 中自行检索。 21 | 22 | ![dyld_shared_cache on macOS](7.png) 23 | 24 | `dyld_shared_cache` 存在于 iOS 设备的 `/System/Library/Caches/com.apple.dyld/` 目录。文件名即为 `dyld_shared_cache_arm*` 加上对应的架构编号。 25 | 26 | ### 从设备提取 `dyld_shared_cache` 27 | 28 | 如果 iOS 设备已经越狱,那么就可以直接从 `/System/Library/Caches/com.apple.dyld/` 目录下找到,拷贝出来即可。 29 | 30 | ![iFunBox](2.png) 31 | 32 | 而如果没有越狱设备,则可以巧妙地使用 Shortcuts(捷径)App 来获取,你可以直接使用我已经编辑好的 [Shortcut](https://www.icloud.com/shortcuts/baa4c53d6cd046f087b5270d715a0b45),运行后,将其 AirDrop 到 Mac 端,解压即可。 33 | 34 | ![Shortcut](3.jpeg) 35 | 36 | ### 提取 `dyld_shared_cache` 37 | 38 | 关于将库从 `dyld_shared_cache` 中还原的工具现在有很多,这里只选取了使用 Apple 开源 dyld 中 dsc_extractor.cpp 来提取。有关更加详细的提取,可以参考 [Extracting libraries from `dyld_shared_cache` - zhuowei](https://worthdoingbadly.com/dscextract/) 一文。 39 | 40 | 下载 Apple Open Source 官网 dyld 代码,找到其中 dsc_extractor.cpp 文件,将其 `main` 函数上方的 `#if 0` 宏置为 `#if 1`,这样 `main` 函数才得以执行。 41 | 42 | 使用 macOS 自带的 clang++ 编译器即可编译:`clang++ -o dsc_extractor ./dsc_extractor.cpp dsc_iterator.cpp`。 43 | 44 | ![dsc_extractor](4.png) 45 | 46 | 最后运行可执行文件,并带上 `dyld_shared_cache_arm64` 路径和要提取到的路径参数,即可,例如:`./dsc_extractor dyld_shared_cache_arm64 ./frameworks`。 47 | 48 | ![提取结果](5.png) 49 | 50 | ## Why 51 | 52 | 在搭载 iOS 9.0.1 的 iPhone 5s 上,`dyld_shared_cache_armv7s` 大小为 518.6 MB,`dyld_shared_cache_arm64` 大小为 619.9 MB。而自 iOS 11 开始全面弃用 32 位应用,因此搭载 iOS 12 的 iPhone X 上仅有 `dyld_shared_cache_arm64`,大小为 1.28 GB。可以看出系统库在逐渐增大,这其中包括新增的 SDK 等。如果不进行整合,系统加载类库每次都需要检索所有需要的动态库,App 的启动时间会剧增。而整合为单一文件,程序启动的压力便会小很多,启动速度和性能便有所提升。 53 | 54 | ## Reference 55 | 56 | - [dyld - Apple Open Source](https://opensource.apple.com/tarballs/dyld/) 57 | - [system_cmds - Apple Open Source](https://opensource.apple.com/tarballs/system_cmds/) 58 | - [`dyld_shared_cache` - iPhoneDevWiki](http://iphonedevwiki.net/index.php/Dyld_shared_cache) 59 | - [Extracting libraries from `dyld_shared_cache` - zhuowei](https://worthdoingbadly.com/dscextract/) 60 | -------------------------------------------------------------------------------- /Posts/Focus/iOS_App_Start_up/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Focus/iOS_App_Start_up/1.png -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo.xcodeproj/xcshareddata/xcschemes/Initialize_Demo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Person+Life.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Life.h 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person (Life) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Person+Life.m: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Life.m 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person+Life.h" 10 | 11 | @implementation Person (Life) 12 | 13 | + (void)initialize { 14 | NSLog(@"Person+Life %s", __func__); 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Person+Work.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Work.h 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person (Work) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Person+Work.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Person+Work.m 4 | // Initialize_Demo 5 | // 6 | // Created by kingcos on 2019/4/22. 7 | // Copyright © 2019 kingcos. All rights reserved. 8 | // 9 | 10 | #import "Person+Work.h" 11 | 12 | @implementation Person (Work) 13 | 14 | + (void)initialize { 15 | NSLog(@"Person+Work %s", __func__); 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Person.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person.h 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person : NSObject 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Person.m: -------------------------------------------------------------------------------- 1 | // 2 | // Person.m 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | @implementation Person 12 | 13 | + (void)initialize { 14 | NSLog(@"Person %s", __func__); 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Programmer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Programmer.h 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Programmer : Person 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Programmer.m: -------------------------------------------------------------------------------- 1 | // 2 | // Programmer.m 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Programmer.h" 10 | 11 | @implementation Programmer 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Student+School.h: -------------------------------------------------------------------------------- 1 | // 2 | // Student+School.h 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Student.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Student (School) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Student+School.m: -------------------------------------------------------------------------------- 1 | // 2 | // Student+School.m 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Student+School.h" 10 | 11 | @implementation Student (School) 12 | 13 | + (void)initialize { 14 | NSLog(@"Student+School %s", __func__); 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Student.h: -------------------------------------------------------------------------------- 1 | // 2 | // Student.h 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Student : Person 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/Student.m: -------------------------------------------------------------------------------- 1 | // 2 | // Student.m 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Student.h" 10 | 11 | @implementation Student 12 | 13 | + (void)initialize { 14 | NSLog(@"Student %s", __func__); 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/Initialize_Demo/Initialize_Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Initialize_Demo 4 | // 5 | // Created by kingcos on 2019/4/22. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import 12 | 13 | #import "Person.h" 14 | #import "Student.h" 15 | #import "Programmer.h" 16 | 17 | int main(int argc, const char * argv[]) { 18 | @autoreleasepool { 19 | NSLog(@"---"); 20 | Student *stu = [Student alloc]; 21 | NSLog(@"---"); 22 | stu = [stu init]; 23 | 24 | NSLog(@"---"); 25 | [Programmer load]; 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Posts/Practice/+initialize_in_iOS/README.md: -------------------------------------------------------------------------------- 1 | # Focus - Obj-C `+ load` 方法剖析 2 | 3 | | Date | Notes | Source Code | 4 | |:-----:|:-----:|:-----:| 5 | | 2019-03-30 | 首次提交 | | 6 | 7 | > 8 | 9 | 10 | 11 | 12 | 13 | 14 | ## Reference 15 | 16 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo.xcodeproj/xcshareddata/xcschemes/Load_Obj-C_Demo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 69 | 70 | 74 | 75 | 76 | 77 | 78 | 79 | 85 | 87 | 93 | 94 | 95 | 96 | 98 | 99 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/Person+Life.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Life.h 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person (Life) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/Person+Life.m: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Life.m 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person+Life.h" 10 | 11 | @implementation Person (Life) 12 | 13 | //+ (void)load { 14 | // NSLog(@"Person+Life %s", __func__); 15 | //} 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/Person+Work.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Work.h 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person (Work) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/Person+Work.m: -------------------------------------------------------------------------------- 1 | // 2 | // Person+Work.m 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person+Work.h" 10 | 11 | @implementation Person (Work) 12 | 13 | //+ (void)load { 14 | // NSLog(@"Person+Work %s", __func__); 15 | //} 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/Person.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person.h 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Person : NSObject 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/Person.m: -------------------------------------------------------------------------------- 1 | // 2 | // Person.m 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | @implementation Person 12 | 13 | //+ (void)load { 14 | // NSLog(@"Person %s", __func__); 15 | //} 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/Student+School.h: -------------------------------------------------------------------------------- 1 | // 2 | // Student+School.h 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Student.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Student (School) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/Student+School.m: -------------------------------------------------------------------------------- 1 | // 2 | // Student+School.m 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Student+School.h" 10 | 11 | @implementation Student (School) 12 | 13 | //+ (void)load { 14 | // NSLog(@"Student+School %s", __func__); 15 | //} 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/Student.h: -------------------------------------------------------------------------------- 1 | // 2 | // Student.h 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Student : Person 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/Student.m: -------------------------------------------------------------------------------- 1 | // 2 | // Student.m 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Student.h" 10 | 11 | @implementation Student 12 | 13 | //+ (void)load { 14 | // [super load]; 15 | // NSLog(@"Student %s", __func__); 16 | //} 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_Demo/Load_Obj-C_Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Load_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/4/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | @autoreleasepool { 13 | // insert code here... 14 | NSLog(@"Hello, World!"); 15 | } 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo.xcodeproj/xcshareddata/xcschemes/Load_Obj-C_iOS_Demo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Load_Obj-C_iOS_Demo 4 | // 5 | // Created by kingcos on 2019/4/20. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Load_Obj-C_iOS_Demo 4 | // 5 | // Created by kingcos on 2019/4/20. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // Load_Obj-C_iOS_Demo 4 | // 5 | // Created by kingcos on 2019/4/20. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // Load_Obj-C_iOS_Demo 4 | // 5 | // Created by kingcos on 2019/4/20. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/Load_Obj-C_iOS_Demo/Load_Obj-C_iOS_Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Load_Obj-C_iOS_Demo 4 | // 5 | // Created by kingcos on 2019/4/20. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | @interface Fruit : NSObject 13 | 14 | @end 15 | 16 | @implementation Fruit 17 | 18 | + (void)load { 19 | NSLog(@"------"); 20 | sleep(3); 21 | NSLog(@"------"); 22 | } 23 | 24 | @end 25 | 26 | int main(int argc, char * argv[]) { 27 | @autoreleasepool { 28 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Posts/Practice/+load_in_iOS/README.md: -------------------------------------------------------------------------------- 1 | # Focus - iOS 中的 + load 方法 2 | 3 | | Date | Notes | Source Code | 4 | |:-----:|:-----:|:-----:| 5 | | 2019-04-13 | 首次提交 | | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ## Reference 14 | 15 | -------------------------------------------------------------------------------- /Posts/Practice/CI_Practice_in_iOS/1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/CI_Practice_in_iOS/1/1.png -------------------------------------------------------------------------------- /Posts/Practice/CI_Practice_in_iOS/1/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/CI_Practice_in_iOS/1/2.png -------------------------------------------------------------------------------- /Posts/Practice/CI_Practice_in_iOS/1/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/CI_Practice_in_iOS/1/3.png -------------------------------------------------------------------------------- /Posts/Practice/CI_Practice_in_iOS/1/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/CI_Practice_in_iOS/1/4.png -------------------------------------------------------------------------------- /Posts/Practice/CI_Practice_in_iOS/1/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/CI_Practice_in_iOS/1/5.png -------------------------------------------------------------------------------- /Posts/Practice/CI_Practice_in_iOS/1/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/CI_Practice_in_iOS/1/6.png -------------------------------------------------------------------------------- /Posts/Practice/CI_Practice_in_iOS/1/README.md: -------------------------------------------------------------------------------- 1 | # Practice - iOS 项目持续集成实践(一) 2 | 3 | ![CI in Practice](https://github.com/kingcos/Perspective/blob/writing/Posts/Practice/CI_Practice_in_iOS/1/image.png?raw=true) 4 | 5 | ## Preface 6 | 7 | 一个软件工程项目从编写、到测试、再最终交付到用户通常有很多重复且固定的步骤。虽然作为开发者,我们的核心任务是编写代码,而这些其他的步骤却也不能忽视,持续集成(Continuous Integration)则可以帮助开发者完成这些琐碎的事务,提升团队的开发效率与质量。 8 | 9 | 本文将主要介绍持续集成是什么,以及其中的好处。当然,您可能也注意到了标题后面「(一)」,没错,持续集成并非一篇文章可以概括,笔者希望尽可能将目前团队中使用到的和持续集成相关的内容进行总结,目的是为了让大家一起思考如何让持续集成更好地服务我们开发。当然,限于笔者能力,文中不免出现遗漏,也望读者能够批评和指出。 10 | 11 | ## What 12 | 13 | 持续集成,译自 Continuous Integration,简称 CI(在下文中,将统一使用该英文简称)。在 Wikipedia 中,也有针对 CI 特别详细且专业的介绍。简而言之,当开发者通过版本控制系统(例如 Git)提交了代码,CI 系统将为其自动执行构建、分析、测试等服务,当前面的服务一致通过,其也能直接将产品部署到生产环境,而后进入下一个循环。其中每一步都将自动触发、执行,结果也将会自动反馈回开发者。正如下图所示,CI 的重点在于 C——持续。 14 | 15 | ![CI](https://github.com/kingcos/Perspective/blob/writing/Posts/Practice/CI_Practice_in_iOS/1/1.png?raw=true) 16 | 17 | ## Why & Why not 18 | 19 | 那么为什么需要 CI 呢?相比于传统的先开发,再测试,后上线的模式有哪些好处呢?在团队使用 CI 这段时间中,得出了以下主要两个好处: 20 | 21 | 1. 及时发现错误。CI 并不能消除错误,但 CI 将发现错误的时机尽可能地提前,所以也更加节省时间来改正错误。当开发者提交代码至代码仓库时,其对于代码的熟悉程度是最高的。如果这个时候尽可能的纠正一些错误或不当,开发者将能很快注意到并将错误改正,避免了由于时间或者团队中其他人对于代码的修改所导致的问题,提升了开发效率。 22 | 2. 自动化。市面上的 CI 平台都给了开发者比较高的自由度,能够执行脚本或命令。因此很多自动化的操作都可以制定好,来自动化地执行,节省开发者的时间。 23 | 24 | 如果这两个显而易见的好处还不足以说服,可以参考文末 Reference 中 EKATERINA NOVOSELTSEVA 的文章。那么 CI 会不会也存在什么难处呢? 25 | 26 | 1. 跨技术栈。CI 并不特定于前端或者后端,CI 通常根据不同的平台而有很多不同,包括配置的方法、使用的语言、自由度等等。CI 又和 Docker 的发展有一定的关系,因此跨技术栈可能让一些团队望而却步。不过好的是,DevOps(Development & Operations)也在国内渐渐兴起,越来越被重视。 27 | 2. 跨平台。这里所指的平台是指代码托管平台、CI 平台、以及部署平台。在公司开始时,可能并不能轻易考虑到后续的发展,因此在原有平台加入 CI 可能需要跨平台的协作。对于一些「黑盒」的平台,有时便难以很好的集成。不过,现在 Git 的两大平台 GitHub 和 GitLab 都很重视且支持 CI 平台,也便于开发者使用。 28 | 29 | 如果后面两个问题并没有阻挠你,那么就开始尝试 CI 吧~ 30 | 31 | ## How 32 | 33 | CI 并不依赖于某种特定的技术栈,其属于一种编程范式。但是,具体谈及如何实践,这就需要结合不同的工具和业务,进行定制。 34 | 35 | ### Jenkins 36 | 37 | ![Jenkins](https://github.com/kingcos/Perspective/blob/writing/Posts/Practice/CI_Practice_in_iOS/1/2.png?raw=true) 38 | 39 | Jenkins 是一款使用 Java 开发且开源的持续集成工具,很多 iOS 团队内部都会使用 Jenkins & Fastlane 来自动化打包。因为 Jenkins 是开源的,可以方便地部署在自己的服务器中,而且也有很多插件来辅助不同的技术栈和功能需求。Swift 官方也使用了 Jenkins 作为自己的 CI。 40 | 41 | ![ci.swift.org](https://github.com/kingcos/Perspective/blob/writing/Posts/Practice/CI_Practice_in_iOS/1/3.png?raw=true) 42 | 43 | ### GitHub with Travis CI 44 | 45 | ![Travis CI](https://github.com/kingcos/Perspective/blob/writing/Posts/Practice/CI_Practice_in_iOS/1/4.png?raw=true) 46 | 47 | GitHub,人尽皆知,是全球最大的代码托管平台,但 GitHub 本身并没有集成 CI。但有很多 CI 平台为 GitHub 定制 CI 环境,其中使用较多的便是 Travis CI。在 GitHub 仓库中看到有 `.travis.yml` 文件便意味着该仓库集成了 Travis CI。对于开源的项目,可以选择它就不用开发者再单独配置服务器来运作 CI,当然速度可能会慢些。之前在写个人的一个命令行工具时,便尝试使用了 Travis CI,而且可以非常容易的将 CI 状态和代码覆盖率的 Budge 标示在项目文档中。 48 | 49 | ![kingcos/WWDCHelper](https://github.com/kingcos/Perspective/blob/writing/Posts/Practice/CI_Practice_in_iOS/1/5.png?raw=true) 50 | 51 | ### GitLab with CI 52 | 53 | ![GitLab](https://github.com/kingcos/Perspective/blob/writing/Posts/Practice/CI_Practice_in_iOS/1/6.png?raw=true) 54 | 55 | 相比于上述的几个平台,GitLab 真正把代码托管和 CI 结合了起来,并在最新 Release 版中加入了 Auto DevOps,似乎是更加先进的 CI。团队内部目前使用的便是 GitLab EE,后续就将以 GitLab 为主,讲讲其中配合 GitLab Runner 来规范化开发流程。 56 | 57 | ## Reference 58 | 59 | - [Continuous integration - Wikipedia](https://en.wikipedia.org/wiki/Continuous_integration) 60 | - [Top benefits of continuous integration - EKATERINA NOVOSELTSEVA](https://apiumtech.com/blog/top-benefits-of-continuous-integration-2/) 61 | - [Jenkins](https://jenkins.io) 62 | - [Travis CI](https://travis-ci.org) 63 | - [GitLab](https://gitlab.com) -------------------------------------------------------------------------------- /Posts/Practice/CI_Practice_in_iOS/1/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/CI_Practice_in_iOS/1/image.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/1.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/10.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/11.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/12.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/13.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/14.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/15.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/16.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/17.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/18.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/19.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/2.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/20.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/21.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/22.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/3.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/4.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/5.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/6.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/7.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/8.png -------------------------------------------------------------------------------- /Posts/Practice/Docker_for_Hadoop/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Docker_for_Hadoop/9.png -------------------------------------------------------------------------------- /Posts/Practice/Locks_in_iOS/README.md: -------------------------------------------------------------------------------- 1 | # Practice - iOS 中的锁(Lock) 2 | 3 | | Date | Notes | Source Code | 4 | |:-----:|:-----:|:-----:| 5 | | 2019-03-08 | 首次提交 | | 6 | 7 | 锁(Lock)是什么?正如 Wikipedia 所说: 8 | 9 | > In computer science, a lock or mutex (from mutual exclusion) is a synchronization mechanism for enforcing limits on access to a resource in an environment where there are many threads of execution. A lock is designed to enforce a mutual exclusion concurrency control policy. 10 | > 11 | > -- Lock (computer science), Wikipedia 12 | > 13 | > 译: 14 | > 在计算机科学中,锁或互斥(mutex,来源于 mutual exclusion,相互排斥)是一种同步机制,用于在多线程执行的环境中强制限制访问资源的访问。锁被设计为强制互斥的并发控制策略。 15 | > 16 | > -- 锁(计算机科学) 17 | 18 | 在计算机中,一块资源(Resource),或者简单地拿一个变量(Variable)来举例,当它加载到内存之后,可能会有许多线程(Thread)去同时访问其所在的内存地址。为了保护这块资源在同一时间只能被有限个线程访问,就可以加上锁,在需要访问的线程访问完毕后,再进行解锁,即可以保证在程序执行时,其是线程安全的。iOS 也是支持多线程的操作系统,锁自然也存在于 iOS 中,那么这篇就简单谈谈 iOS 中锁的概念,以及相关的 API。 19 | 20 | ## NSLock 21 | 22 | NSLock 是 23 | 24 | 25 | 26 | 27 | 28 | 29 | ## Reference 30 | 31 | - [Wikipedia - Lock (computer science)](https://en.wikipedia.org/wiki/Lock_(computer_science)) -------------------------------------------------------------------------------- /Posts/Practice/Multithread_Techs_in_iOS/2-NSThread/README.md: -------------------------------------------------------------------------------- 1 | # Practice - iOS 多线程技术实践之 NSThread 2 | 3 | | Date | Notes | Swift | Xcode | 4 | |:-----:|:-----:|:-----:|:-----:| 5 | | 2019-03-11 | 首次提交 | 4.2 | 10.1 | 6 | 7 | > 在 iOS 中的多线程(Multithreading)技术通常有以下几种实现方式:pthreads、`NSThread`、GCD、`NSOperation`。这次,我们来一起看一看 `NSThread`。 8 | 9 | ## Preface 10 | 11 | ## One more thing... 12 | 13 | ## Reference 14 | -------------------------------------------------------------------------------- /Posts/Practice/Multithread_Techs_in_iOS/iOS_Multithread_Tech_Demo/iOS_Multithread_Tech_Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Posts/Practice/Multithread_Techs_in_iOS/iOS_Multithread_Tech_Demo/iOS_Multithread_Tech_Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Posts/Practice/Multithread_Techs_in_iOS/iOS_Multithread_Tech_Demo/iOS_Multithread_Tech_Demo/POSIXThreadManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // POSIXThreadManager.h 3 | // iOS_Multithread_Tech_Demo 4 | // 5 | // Created by kingcos on 2019/3/8. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface POSIXThreadManager : NSObject 14 | 15 | + (void)pthread_create_demo; 16 | + (void)pthread_join_demo; 17 | + (void)thread_conflict_demo; 18 | + (void)semaphore_demo; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Posts/Practice/Multithread_Techs_in_iOS/iOS_Multithread_Tech_Demo/iOS_Multithread_Tech_Demo/iOS_Multithread_Tech_Demo-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /Posts/Practice/Multithread_Techs_in_iOS/iOS_Multithread_Tech_Demo/iOS_Multithread_Tech_Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // iOS_Multithread_Tech_Demo 4 | // 5 | // Created by kingcos on 2019/3/8. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "POSIXThreadManager.h" 12 | 13 | int main(int argc, const char * argv[]) { 14 | @autoreleasepool { 15 | // [POSIXThreadManager pthread_create_demo]; 16 | // [POSIXThreadManager pthread_join_demo]; 17 | // [POSIXThreadManager thread_conflict_demo]; 18 | // [POSIXThreadManager semaphore_demo]; 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Posts/Practice/Multithread_Techs_in_iOS/iOS_Multithread_Tech_Demo_Swift/iOS_Multithread_Tech_Demo_Swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Posts/Practice/Multithread_Techs_in_iOS/iOS_Multithread_Tech_Demo_Swift/iOS_Multithread_Tech_Demo_Swift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Posts/Practice/Multithread_Techs_in_iOS/iOS_Multithread_Tech_Demo_Swift/iOS_Multithread_Tech_Demo_Swift/PThreadsManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PThreadsManager.swift 3 | // iOS_Multithread_Tech_Demo 4 | // 5 | // Created by kingcos on 2019/3/10. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class PThreadsManager { 12 | class func tryCreate() { 13 | var thread_1, thread_2: pthread_t? 14 | 15 | if pthread_create(&thread_1, nil, runForCreate, encode("Thread 1")) != 0 { 16 | print("pthread_create thread_1 error.") 17 | exit(1) 18 | } 19 | 20 | if pthread_create(&thread_2, nil, runForCreate, encode("Thread 2")) != 0 { 21 | print("pthread_create thread_2 error.") 22 | exit(1) 23 | } 24 | 25 | sleep(1) 26 | exit(3) 27 | } 28 | 29 | class func tryJoin() { 30 | var thread_1, thread_2: pthread_t? 31 | 32 | if pthread_create(&thread_1, nil, runForJoin, encode("Thread 1")) != 0 { 33 | print("pthread_create thread_1 error.") 34 | exit(1) 35 | } 36 | 37 | if pthread_create(&thread_2, nil, runForJoin, encode("Thread 2")) != 0 { 38 | print("pthread_create thread_2 error.") 39 | exit(1) 40 | } 41 | 42 | if pthread_join(thread_1!, nil) != 0 { 43 | print("pthread_join thread_1 error.") 44 | exit(1) 45 | } 46 | 47 | if pthread_join(thread_2!, nil) != 0 { 48 | print("pthread_join thread_2 error.") 49 | exit(1) 50 | } 51 | } 52 | 53 | class func tryMutex() { 54 | var thread_1, thread_2: pthread_t? 55 | 56 | if pthread_mutex_init(&mutex, nil) != 0 { 57 | print("pthread_mutex_init error.") 58 | } 59 | 60 | if pthread_create(&thread_1, nil, runForMutex, encode("Thread 1")) != 0 { 61 | print("pthread_create thread_1 error.") 62 | exit(1) 63 | } 64 | 65 | if pthread_create(&thread_2, nil, runForMutex, encode("Thread 2")) != 0 { 66 | print("pthread_create thread_2 error.") 67 | exit(1) 68 | } 69 | 70 | if pthread_join(thread_1!, nil) != 0 { 71 | print("pthread_join thread_1 error.") 72 | exit(1) 73 | } 74 | 75 | if pthread_join(thread_2!, nil) != 0 { 76 | print("pthread_join thread_2 error.") 77 | exit(1) 78 | } 79 | 80 | print("Result count \(current_count)") 81 | } 82 | 83 | class func trySemaphore() { 84 | var thread_1, thread_2: pthread_t? 85 | 86 | if pthread_create(&thread_1, nil, runForSemaphore1, encode("Thread 1")) != 0 { 87 | print("pthread_create thread_1 error.") 88 | exit(1) 89 | } 90 | 91 | if pthread_create(&thread_2, nil, runForSemaphore2, encode("Thread 2")) != 0 { 92 | print("pthread_create thread_2 error.") 93 | exit(1) 94 | } 95 | 96 | if pthread_join(thread_1!, nil) != 0 { 97 | print("pthread_join thread_1 error.") 98 | exit(1) 99 | } 100 | 101 | if pthread_join(thread_2!, nil) != 0 { 102 | print("pthread_join thread_2 error.") 103 | exit(1) 104 | } 105 | } 106 | } 107 | 108 | let START_NUMBER = 0 109 | let END_NUMBER = 10 110 | let THREAD_NUMBER = 2 111 | let COUNT_PER_THREAD = (END_NUMBER - START_NUMBER) / THREAD_NUMBER 112 | 113 | var current_count = START_NUMBER 114 | var mutex = pthread_mutex_t() 115 | 116 | var sem: [CChar] = "sem".cString(using: String.Encoding.utf8)! 117 | var semaphore = sem_open(&sem, 0, 0, 0) 118 | 119 | func runForCreate(_ context: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { 120 | print("\(decode(context) as String) is running.") 121 | exit(2) 122 | } 123 | 124 | func runForJoin(_ context: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { 125 | print("\(decode(context) as String) is running.") 126 | exit(2) 127 | } 128 | 129 | func runForMutex(_ context: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { 130 | for _ in 0.. UnsafeMutableRawPointer? { 143 | if sem_wait(semaphore) != 0 { 144 | perror("sem_wait error.") 145 | exit(1) 146 | } 147 | print("runForSemaphore1") 148 | pthread_exit(nil) 149 | } 150 | 151 | func runForSemaphore2(_ context: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { 152 | sleep(1) 153 | 154 | if sem_post(semaphore) != 0 { 155 | print("sem_post error.") 156 | exit(1) 157 | } 158 | 159 | print("runForSemaphore2") 160 | pthread_exit(nil) 161 | } 162 | 163 | class Box { 164 | let value: T 165 | 166 | init(_ value: T) { 167 | self.value = value 168 | } 169 | } 170 | 171 | private func decode(_ memory: UnsafeMutableRawPointer) -> T { 172 | let unmanaged = Unmanaged>.fromOpaque(memory) 173 | defer { unmanaged.release() } 174 | return unmanaged.takeUnretainedValue().value 175 | } 176 | 177 | private func encode(_ t: T) -> UnsafeMutableRawPointer { 178 | return Unmanaged.passRetained(Box(t)).toOpaque() 179 | } 180 | -------------------------------------------------------------------------------- /Posts/Practice/Multithread_Techs_in_iOS/iOS_Multithread_Tech_Demo_Swift/iOS_Multithread_Tech_Demo_Swift/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // iOS_Multithread_Tech_Demo_Swift 4 | // 5 | // Created by kingcos on 2019/3/10. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //PThreadsManager.tryCreate() 12 | //PThreadsManager.tryJoin() 13 | //PThreadsManager.tryMutex() 14 | //PThreadsManager.trySemaphore() 15 | -------------------------------------------------------------------------------- /Posts/Practice/NSCoding_in_iOS/README.md: -------------------------------------------------------------------------------- 1 | # Practice - iOS 中的归档(Archive)相关 2 | 3 | | Date | Notes | Source Code | 4 | |:-----:|:-----:|:-----:| 5 | | 2019-03-08 | 首次提交 | | 6 | 7 | ## What 8 | 9 | 虽然我非常喜欢使用 Swift 来开发 iOS,但现实是还有很多机会能够接触到 Obj-C。在目前阶段,完全摒弃 Obj-C 是不现实的,毕竟 UIKit 仍然是由 Obj-C 编写的。 10 | 11 | 今天来谈谈 Obj-C 中归档相关的内容。在官方文档中,还有另外一个类似作用的机制称作序列化(Serialization)。这里的序列化特指 iOS 中序列化属性列表(Property list,即 plist)并不是广义上的序列化。它们两者都可以将结构化数据转换为与结构无关的字节流,便于传输,也可以在需要时解码为结构化数据。序列化部分并不属于本文的重点,下面将简述略过。 12 | 13 | ### Serializing Property Lists 14 | 15 | 序列化属性列表并不会记录值的数据类型,也不会记录它们之间的关系,只有值本身才会被记录。 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ## NSCoder/NSCoding 29 | 30 | `NSCoding` 是 Obj-C 中的一个协议,总共包含以下两个方法: 31 | 32 | ```objc 33 | @protocol NSCoding 34 | 35 | // 使用 NSCoder 编码器编码 36 | - (void)encodeWithCoder:(NSCoder *)aCoder; 37 | // 使用 NSCoder 反编码器反编码 38 | - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; // NS_DESIGNATED_INITIALIZER 39 | 40 | @end 41 | ``` 42 | 43 | 44 | 45 | 46 | 47 | ## NSSecureCoding 48 | 49 | 50 | ## NSCopying 51 | 52 | 53 | 54 | ## Reference 55 | 56 | - [Apple Inc. - Archives and Serializations Programming Guide](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Archiving/Archiving.html) -------------------------------------------------------------------------------- /Posts/Practice/NumPy_Basics/README.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Machine Learning\n", 8 | "\n", 9 | "## Basics\n", 10 | "\n", 11 | "### 数据\n", 12 | "\n", 13 | "#### Terms\n", 14 | "\n", 15 | "- 数据集(Data Set)\n", 16 | "- 样本(Sample)\n", 17 | "- 特征(Feature):通常用 $X$ 表示(通常是矩阵)\n", 18 | " - 第 $i$ 个样本行:$X^{(i)}$(特征向量)\n", 19 | " - 第 $i$ 个样本第 $j$ 个特征值:$X^{(i)}_{1}$\n", 20 | "- 标记(Label):通常用 $y$ 表示(向量)\n", 21 | " - 第 $i$ 个样本的标记:$y^{(i)}$\n", 22 | "- 特征空间(Feature Space)\n", 23 | "\n", 24 | "\n", 25 | "\n", 26 | "- 分类任务本质就是在特征空间切分\n", 27 | "- 在高维空间同理\n", 28 | "- 特征可以很抽象\n", 29 | " - 图像,每一个像素点都是特征点\n", 30 | " - MNIST:28 * 28 的图像即有 28 * 28 = 784 个特征\n", 31 | " - 如果是彩色图像特征更多\n", 32 | "\n", 33 | "#### 基本任务\n", 34 | "\n", 35 | "- 监督学习\n", 36 | " - 给机器的训练数据拥有「标记」或者「答案」\n", 37 | " - 分类\n", 38 | " - 二分类\n", 39 | " - 多分类\n", 40 | " - 多标签分类\n", 41 | " - 回归(结果是一个连续数字的值,而非一个类别)\n", 42 | " - 算法:k 近邻,线性回归,多项式回归,逻辑回归,SVM,决策树,随机森林 \n", 43 | "- 非监督学习\n", 44 | " - 给机器的训练数据没有任何「标记」或者「答案」\n", 45 | " - 对没有「标记」的数据进行分类 - 聚类分析\n", 46 | " - 意义\n", 47 | " - 对数据进行降维处理\n", 48 | " - 特征提取:信用卡的信用评级和人的胖瘦无关?\n", 49 | " - 特征压缩:PCA\n", 50 | " - 意义:方便可视化\n", 51 | " - 异常检测\n", 52 | "- 半监督学习\n", 53 | " - 一部分数据有「标记」或者「答案」,另一部分数据没有\n", 54 | " - 更常见于:各种原因产生的标记缺失\n", 55 | " - 通常都先使用无监督学习手段对数据做处理,之后使用监督学习手段做模型的训练和预测\n", 56 | "- 增强学习\n", 57 | " - 根据周围环境的情况,采取行动,根据采取行动的结果,学习行动方式\n", 58 | " - AlphaGo\n", 59 | "\n", 60 | "\n", 61 | "- 在线学习 Online Learning\n", 62 | " - 及时反映新的环境变化\n", 63 | " - 需要加强对数据进行监控(异常检测)\n", 64 | "- 批量学习 Batch Learning\n", 65 | " - 又称离线学习 Offline Learning\n", 66 | " - 优点:简单\n", 67 | " - 如何适应环境变化?\n", 68 | " - 定时重新批量学习\n", 69 | "\n", 70 | "- 参数学习(Parametric Learning)\n", 71 | " - 一旦学到了参数,就不再需要原有的数据集\n", 72 | "- 非参数学习(Nonparametric Learning)\n", 73 | " - 不对模型进行过多假设\n", 74 | " - 非参数不等于没参数" 75 | ] 76 | } 77 | ], 78 | "metadata": { 79 | "kernelspec": { 80 | "display_name": "Python 3", 81 | "language": "python", 82 | "name": "python3" 83 | }, 84 | "language_info": { 85 | "codemirror_mode": { 86 | "name": "ipython", 87 | "version": 3 88 | }, 89 | "file_extension": ".py", 90 | "mimetype": "text/x-python", 91 | "name": "python", 92 | "nbconvert_exporter": "python", 93 | "pygments_lexer": "ipython3", 94 | "version": "3.6.4" 95 | } 96 | }, 97 | "nbformat": 4, 98 | "nbformat_minor": 2 99 | } 100 | -------------------------------------------------------------------------------- /Posts/Practice/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Posts/Practice/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Posts/Practice/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection.xcodeproj/xcshareddata/xcschemes/Type_Introspection_and_Reflection.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Posts/Practice/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Obj-C/Person.h: -------------------------------------------------------------------------------- 1 | // 2 | // Person.h 3 | // Type_Introspection_and_Reflection 4 | // 5 | // Created by 买明 on 2019/4/10. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | /** 14 | Fruit class 15 | */ 16 | @interface Fruit : NSObject 17 | - (void)taste; 18 | @end 19 | 20 | /** 21 | Apple class 22 | */ 23 | @interface Apple : Fruit 24 | - (void)tasteApple; 25 | @end 26 | 27 | /** 28 | Orange class 29 | */ 30 | @interface Orange : Fruit 31 | - (void)tasteOrange; 32 | @end 33 | 34 | /** 35 | Person class 36 | */ 37 | @interface Person : NSObject 38 | - (void)eat:(id)fruit; 39 | 40 | + (void)introspectionDemo; 41 | + (void)reflectionDemo; 42 | @end 43 | 44 | NS_ASSUME_NONNULL_END 45 | -------------------------------------------------------------------------------- /Posts/Practice/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Obj-C/Person.m: -------------------------------------------------------------------------------- 1 | // 2 | // Person.m 3 | // Type_Introspection_and_Reflection 4 | // 5 | // Created by 买明 on 2019/4/10. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Person.h" 10 | #import 11 | 12 | @implementation Fruit 13 | - (void)taste { 14 | NSLog(@"%@ - %s", NSStringFromClass(self.class), __func__); 15 | } 16 | @end 17 | 18 | @implementation Apple 19 | - (void)tasteApple { 20 | NSLog(@"%@ - %s", NSStringFromClass(self.class), __func__); 21 | } 22 | @end 23 | 24 | @implementation Orange 25 | - (void)tasteOrange { 26 | NSLog(@"%@ - %s", NSStringFromClass(self.class), __func__); 27 | } 28 | @end 29 | 30 | @implementation Person 31 | - (void)eat:(id)fruit { 32 | // 检查是否是 Fruit 类或其子类 33 | if ([fruit isKindOfClass:Fruit.class]) { 34 | if ([fruit isMemberOfClass:Apple.class]) { 35 | // 检查是否是 Apple 类 36 | [(Apple *)fruit tasteApple]; 37 | } else if ([fruit isMemberOfClass:Orange.class]) { 38 | // 检查是否是 Orange 类 39 | [(Orange *)fruit tasteOrange]; 40 | } else { 41 | [fruit taste]; 42 | } 43 | } 44 | } 45 | 46 | + (void)introspectionDemo { 47 | Person *person = [[Person alloc] init]; 48 | Apple *apple = [[Apple alloc] init]; 49 | 50 | [person eat:apple]; 51 | } 52 | 53 | + (void)reflectionDemo { 54 | id person = [[NSClassFromString(@"Person") alloc] init]; 55 | id orange = [[NSClassFromString(@"Orange") alloc] init]; 56 | [person performSelector:NSSelectorFromString(@"eat:") withObject:orange]; 57 | } 58 | @end 59 | -------------------------------------------------------------------------------- /Posts/Practice/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Obj-C/Type_Introspection_and_Reflection-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "Person.h" 6 | -------------------------------------------------------------------------------- /Posts/Practice/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Swift/Animal.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Animal.swift 3 | // Type_Introspection_and_Reflection 4 | // 5 | // Created by 买明 on 2019/4/10. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class Toy: NSObject { 12 | func playWithToy() { 13 | print(#function) 14 | } 15 | } 16 | 17 | class Ball: Toy { 18 | func playWithBall() { 19 | print(#function) 20 | } 21 | } 22 | 23 | class Doll: Toy { 24 | func playWithDoll() { 25 | print(#function) 26 | } 27 | } 28 | 29 | struct ToyCar { 30 | func playWithToyCar() { 31 | print(#function) 32 | } 33 | } 34 | 35 | class Animal { 36 | func play(_ toy: AnyObject) { 37 | // 检查是否是 Toy 或其子类 38 | if toy.isKind(of: Toy.self) { 39 | if toy.isMember(of: Ball.self) { 40 | // 检查是否是 Ball 类 41 | (toy as! Ball).playWithBall() 42 | } else if toy.isMember(of: Doll.self) { 43 | // 检查是否是 Doll 类 44 | (toy as! Doll).playWithDoll() 45 | } else { 46 | (toy as! Toy).playWithToy() 47 | } 48 | } 49 | } 50 | 51 | func play2(_ toy: Any) { 52 | // 检查是否是 Toy 或其子类 53 | if toy is Toy { 54 | (toy as! Toy).playWithToy() 55 | } else if (toy is ToyCar) { 56 | // 检查是否是 ToyCar 结构体类型 57 | (toy as! ToyCar).playWithToyCar() 58 | } 59 | } 60 | 61 | class func introspectionDemo() { 62 | let ball = Ball() 63 | let dog = Animal() 64 | 65 | dog.play(ball) 66 | } 67 | 68 | class func introspectionDemo2() { 69 | let car = ToyCar() 70 | let dog = Animal() 71 | 72 | dog.play2(car) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Posts/Practice/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Swift/Computer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Computer.swift 3 | // Type_Introspection_and_Reflection 4 | // 5 | // Created by 买明 on 2019/4/11. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Computer { 12 | var system: String 13 | var memorySize: Int 14 | 15 | let run: () -> Void = { 16 | print(#function) 17 | } 18 | 19 | let runWithParam: (String) -> Void = { param in 20 | print("param: \(param)") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Posts/Practice/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/Type_Introspection_and_Reflection/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // Type_Introspection_and_Reflection 4 | // 5 | // Created by kingcos on 2019/4/10. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // Obj-C 12 | print("--- Obj-C introspection demo: ---") 13 | Person.introspectionDemo() 14 | 15 | print("--- Obj-C reflection demo: ---") 16 | Person.reflectionDemo() 17 | 18 | // Swift 19 | print("--- Swift introspection demo 1: ---") 20 | Animal.introspectionDemo() 21 | print("--- Swift introspection demo 2: ---") 22 | Animal.introspectionDemo2() 23 | 24 | // Swift Inflection 25 | print("--- Swift reflection demo: ---") 26 | let cpt = Computer(system: "macOS", memorySize: 16) 27 | let mirror = Mirror(reflecting: cpt) 28 | 29 | if let displayStyle = mirror.displayStyle { 30 | print("mirror's style: \(displayStyle).") 31 | } 32 | 33 | print("mirror's properties count: \(mirror.children.count)") 34 | 35 | for (label, value) in mirror.children { 36 | switch value { 37 | case let function as () -> Void: 38 | function() 39 | case let function as (String) -> Void: 40 | function("Param") 41 | default: 42 | print("\(label ?? "nil") - \(value)") 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Posts/Practice/Weakly_Collections/Weekly_Collections_Demo.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Swift 4.1 - Xcode 9.3 2 | // Powered by [Kingcos](https://github.com/kingcos) 3 | 4 | import UIKit 5 | 6 | class Pencil { 7 | var type: String 8 | var price: Double 9 | 10 | init(_ type: String, _ price: Double) { 11 | self.type = type 12 | self.price = price 13 | } 14 | } 15 | 16 | CFGetRetainCount(Pencil("2B", 1.0) as CFTypeRef) 17 | // 1 18 | 19 | let pencil2B = Pencil("2B", 1.0) 20 | let pencilHB = Pencil("HB", 2.0) 21 | 22 | CFGetRetainCount(pencil2B as CFTypeRef) 23 | CFGetRetainCount(pencilHB as CFTypeRef) 24 | // 2 2 25 | 26 | let pencilBox = [pencil2B, pencilHB] 27 | 28 | CFGetRetainCount(pencil2B as CFTypeRef) 29 | CFGetRetainCount(pencilHB as CFTypeRef) 30 | // 3 3 31 | 32 | final class WeakBox { 33 | weak var unbox: A? 34 | init(_ value: A) { 35 | unbox = value 36 | } 37 | } 38 | 39 | struct WeakArray { 40 | private var items: [WeakBox] = [] 41 | 42 | init(_ elements: [Element]) { 43 | items = elements.map { WeakBox($0) } 44 | } 45 | } 46 | 47 | extension WeakArray: Collection { 48 | var startIndex: Int { return items.startIndex } 49 | var endIndex: Int { return items.endIndex } 50 | 51 | subscript(_ index: Int) -> Element? { 52 | return items[index].unbox 53 | } 54 | 55 | func index(after idx: Int) -> Int { 56 | return items.index(after: idx) 57 | } 58 | } 59 | 60 | let weakPencilBox1 = WeakArray([pencil2B, pencilHB]) 61 | 62 | CFGetRetainCount(pencil2B as CFTypeRef) 63 | CFGetRetainCount(pencilHB as CFTypeRef) 64 | // 3 3 65 | 66 | let firstElement = weakPencilBox1.filter { $0 != nil }.first 67 | firstElement!!.type 68 | // 2B 69 | 70 | CFGetRetainCount(pencil2B as CFTypeRef) 71 | CFGetRetainCount(pencilHB as CFTypeRef) 72 | // 4 3 Note: 这里的 4 是因为 firstElement 持有(Retain)了 pencil2B,导致其引用计数增 1 73 | 74 | let weakPencilBox2 = NSPointerArray.weakObjects() 75 | 76 | let pencil2BPoiter = Unmanaged.passUnretained(pencil2B).toOpaque() 77 | let pencilHBPoiter = Unmanaged.passUnretained(pencilHB).toOpaque() 78 | 79 | CFGetRetainCount(pencil2B as CFTypeRef) 80 | CFGetRetainCount(pencilHB as CFTypeRef) 81 | // 4 3 82 | 83 | weakPencilBox2.addPointer(pencil2BPoiter) 84 | weakPencilBox2.addPointer(pencilHBPoiter) 85 | 86 | CFGetRetainCount(pencil2B as CFTypeRef) 87 | CFGetRetainCount(pencilHB as CFTypeRef) 88 | // 4 3 89 | 90 | // NSHashTable - Set 91 | let weakPencilSet = NSHashTable(options: .weakMemory) 92 | let weakPencilSet2 = NSHashTable.weakObjects() 93 | 94 | weakPencilSet.add(pencil2B) 95 | weakPencilSet.add(pencilHB) 96 | 97 | // NSMapTable - Dictionary 98 | class Eraser { 99 | var type: String 100 | 101 | init(_ type: String) { 102 | self.type = type 103 | } 104 | } 105 | 106 | let weakPencilDict = NSMapTable(keyOptions: .strongMemory, 107 | valueOptions: .weakMemory) 108 | let weakPencilDict2 = NSMapTable.strongToWeakObjects() 109 | 110 | let paintingEraser = Eraser("Painting") 111 | 112 | weakPencilDict.setObject(pencil2B, forKey: paintingEraser) 113 | -------------------------------------------------------------------------------- /Posts/Practice/Weakly_Collections/Weekly_Collections_Demo.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Posts/Practice/Weakly_Collections/Weekly_Collections_Demo.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Posts/Practice/Weakly_Collections/Weekly_Collections_Demo.playground/playground.xcworkspace/xcuserdata/kingcos.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/Weakly_Collections/Weekly_Collections_Demo.playground/playground.xcworkspace/xcuserdata/kingcos.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Posts/Practice/ivar_Access_Control_in_Obj-C/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Practice/ivar_Access_Control_in_Obj-C/1.png -------------------------------------------------------------------------------- /Posts/Promotion/CMU_INI_Kobe/2-1_How_To_Apply/README.md: -------------------------------------------------------------------------------- 1 | # Promotion - 如何申请 2 | 3 | - 链接:[https://www.cmu.edu/ini/admissions/howtoapply.html](https://www.cmu.edu/ini/admissions/howtoapply.html) 4 | 5 | ## 申请截止日期 6 | 7 | | 神户双学位 | 8 | |:-----:| 9 | | 1 月 6 日 | 10 | 11 | ## 如何申请 12 | 13 | ### Kobe MSIT-IS 14 | 15 | #### 最低要求 16 | 17 | - 本科学历,技术专业,至少累积 QPA(Quality Point Average)为 3.0 或同等学历 18 | - 希望在美国期间在硅谷学习的学生需要获得计算机科学、电气和计算机工程或相关领域的学士学位。 19 | - 顺利完成计算机科学或信息技术本科入门课程 20 | - 根据招生委员会的判断,可以通过适当的专业/行业经验得以宽限。 21 | - 具备分析能力,包括顺利完成本科概率或统计学课程 22 | - 根据招生委员会的判断,可以通过适当的专业/行业经验得以宽限。 23 | - 非母语人士的英语水平 24 | 25 | #### 申请提交内容与细节 26 | 27 | > 若申请双学位或单学位(Kobe MSIT-IS)项目,申请人必须填写并向信息网络学院提交申请。申请入学必须提交以下文件: 28 | 29 | 1. 完整的[网上申请表](https://gradadmissions.engineering.cmu.edu/apply/) 30 | - 所有申请和推荐必须在线提交。 31 | - 申请人不得上传 WES 报告;除非要求,否则不接受,上传后将被删除。 32 | - 接受报名的被录取者必须准备好出示本科毕业证明。证明包括最终正式成绩单和学位证书和/或文凭,最迟在 7 月底按照 INI 要求的方式提交。毕业证明是入学的一个条件。提交申请是满足这一要求的协议。未提交毕业证明可能导致终止注册。 33 | - ETS 报告(GRE 和托福)只能通过 ETS 提交。从申请人那里收到的硬拷贝不是官方的。您可以将非官方评分结果直接上传到在线申请中。 34 | 2. 所有非正式文件 35 | - 非正式的成绩单应该上传到网上申请。上传你在本科和研究生阶段就读的所有学院和/或大学的成绩单,无论你是否获得了该学院或大学的学位。 36 | - 所有用外语书写的成绩单和学位证书必须用原文提交,并有英文译文。 37 | - 未完成本科学业的申请人可以提出申请;不过,成绩单必须至少显示六(6)个已完成的学期。 38 | - 如果提交并被录取,作为录取条件,必须不迟于 7 月底提交毕业证明(参见「录取」下的「提交包裹」)。毕业证明包括最终正式成绩单、最终正式成绩单以及临时证书、毕业证书和/或学位证书和/或文凭的质量影印件。未按要求或根本未能提供这些文件,或未能毕业将导致终止注册。 39 | - 接受报名的被录取者将被告知如何正确提交毕业证明。在正式请求之前提交给 INI 的学术记录可能会被丢弃。 40 | 3. 三封推荐信(英文,仅在线) 41 | - 其中至少有两人应该来自教师或最近的雇主。 42 | - 推荐你的人应该很了解你,能够评估你的工作质量。 43 | 4. 正式研究生入学考试(GRE)一般考试成绩 44 | - GRE 是必需的;GMAT 或 GRE 科目考试都不接受审查。在 INI 收到正式的考试成绩副本之前,申请不会被认为是完整的。如果 GRE 成绩超过 5 年,将不被接受。 45 | - 要通过教育测试服务(ETS)提交 GRE 测试结果,请使用以下代码:`#2074` (卡内基梅隆大学U),部门代码 `#0404`(信息科学)。 46 | - 为确保 GRE 成绩在申请截止日期前到达 INI 办公室,申请人应不迟于 11 月参加 GRE 考试。 47 | 5. 如果适用,英语作为外语的正式考试(托福)成绩 48 | - 如果你是一个母语不是英语的申请者,托福是必需的。如果申请人所在国家不提供基于互联网的考试(iBT),INI 将接受 PBT(纸质考试)分数。国际英语语言测试系统(IELTS)也将被接受,以证明ESL熟练程度。 49 | - 要通过教育考试服务(ETS)提交托福考试成绩,请使用以下代码:`Institution #2074, Department`(不需要部门,但如果需要,您可以使用 99 来「未指定的部门」)。 50 | - 没有规定考试成绩的申请入学决定可能会被推迟。 51 | - 已在美国认可大学修读并毕业四年制本科学位课程的申请人,可豁免这项规定。 52 | - 在美国大学修读研究生课程的申请人应该提交一份他们最近一次托福考试的复印件以供评估。INI 可以要求额外的信息来证明足够的 ESL 技能。 53 | 6. 论文和兴趣领域问题 54 | - 必须在线提交,因为硬拷贝声明将不被接受。 55 | - 所有的技术和其他证书都应该列在简历上。研究项目应在网上申请中的论文部分解决。 56 | 7. 两项不可退回的申请费 57 | - 申请双学位课程的人必须向卡内基梅隆大学信息网络学院提交 75 美元的不可退还申请费(见下文地址)。 58 | - 申请双学位的申请人还必须提交不可退还的 3 万日元申请费 59 | - 申请单学位课程(Kobe MSIT-IS)的人必须将您的 INI 支票付款和补充文件邮寄到以下地址 60 | 61 | > Graduate School of Applied Informatics, University of Hyogo 62 | > 63 | > 7-1-28 Minatojima-minami-machi, Chuo-ku 64 | > 65 | > Kobe, 650-0047 Japan 66 | > 67 | > Tel: +81-78-303-2050 68 | > 69 | > Fax: +81-78-303-2055 70 | 71 | > Information Networking Institute 72 | > 73 | > Admissions Committee 74 | > 75 | > Carnegie Mellon University 76 | > 77 | > 4616 Henry Street Pittsburgh, PA 15213-3890 78 | > 79 | > USA 80 | > 81 | > *如果使用快递,请带上 INI 主号码:(412) 268-7195* -------------------------------------------------------------------------------- /Posts/Promotion/CMU_INI_Kobe/README.md: -------------------------------------------------------------------------------- 1 | # Promotion - CMU INI Kobe 2 | 3 | - [1-4 神户信息安全双学位](1-4_Kobe_Information_Security_Dual_Degree) 4 | - [2-1 如何申请](2-1_How_To_Apply) 5 | 6 | ## Reference 7 | 8 | - [Information Networking Institute](https://www.cmu.edu/ini/academics/index.html) 9 | - [Dual-Degree Program INI](http://www.cmuj.jp) -------------------------------------------------------------------------------- /Posts/Promotion/Machine_Learning/ML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Promotion/Machine_Learning/ML.png -------------------------------------------------------------------------------- /Posts/Promotion/Machine_Learning/README.md: -------------------------------------------------------------------------------- 1 | # Promotion - Machine Learning 2 | 3 | ![Machine Learning](ML.png) 4 | 5 | ## Goal 6 | 7 | 完成一款利用机器学习的应用。 8 | 9 | ## Road Map 10 | 11 | ### Linear Algebra 12 | -------------------------------------------------------------------------------- /Posts/Promotion/Machine_Learning/Road_Map/1-Math-Linear_Algebra/Vector/Vector/Matrix.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Matrix.swift 3 | // Vector 4 | // 5 | // Created by kingcos on 2019/2/26. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Matrix: CustomStringConvertible { 12 | private var values: [[Double]] 13 | 14 | var size: Int { 15 | return shape().rows * shape().columns 16 | } 17 | 18 | var description: String { 19 | return "Matrix({\(values)})" 20 | } 21 | 22 | init(_ values: [[Double]]) { 23 | self.values = values 24 | } 25 | 26 | func shape() -> (rows: Int, columns: Int) { 27 | return (values.count, values.first?.count ?? 0) 28 | } 29 | 30 | func get(_ pos: (row: Int, column: Int)) -> Double { 31 | return values[pos.row][pos.column] 32 | } 33 | 34 | func rowVector(_ row: Int) -> Vector { 35 | assert(row <= shape().rows, "Row is out of range.") 36 | return Vector(values[row]) 37 | } 38 | 39 | func columnVector(_ column: Int) -> Vector { 40 | assert(column <= shape().columns, "Column is out of range.") 41 | return Vector(values.compactMap { $0[column] }) 42 | } 43 | } 44 | 45 | extension Matrix { 46 | static func zero(_ shape: (rows: Int, columns: Int)) -> Matrix { 47 | return Matrix([[Double]](repeating: [Double](repeating: 0.0, count: shape.columns), 48 | count: shape.rows)) 49 | } 50 | 51 | static func + (left: Matrix, right: Matrix) -> Matrix { 52 | var left = left 53 | assert(left.shape() == right.shape(), 54 | "Error in adding. Length of matrixes must be same.") 55 | 56 | right.values.enumerated().forEach { t in 57 | t.element.enumerated().forEach { 58 | left.values[t.offset][$0.offset] += $0.element 59 | } 60 | } 61 | 62 | return left 63 | } 64 | 65 | static func - (left: Matrix, right: Matrix) -> Matrix { 66 | var left = left 67 | assert(left.shape() == right.shape(), 68 | "Error in subtracting. Length of matrixes must be same.") 69 | 70 | right.values.enumerated().forEach { t in 71 | t.element.enumerated().forEach { 72 | left.values[t.offset][$0.offset] -= $0.element 73 | } 74 | } 75 | 76 | return left 77 | } 78 | 79 | static func * (left: Double, right: Matrix) -> Matrix { 80 | return Matrix(right.values.map { t in t.map { $0 * left } }) 81 | } 82 | 83 | static func * (left: Matrix, right: Double) -> Matrix { 84 | return right * left 85 | } 86 | } 87 | 88 | extension Matrix { 89 | func rows() -> [Vector] { 90 | return values.map { Vector($0) } 91 | } 92 | 93 | func columns() -> [Vector] { 94 | var columns = [Vector]() 95 | for i in 0.. Vector { 102 | assert(left.shape().columns == right.len, 103 | "Error in Matrix-Matrix Multiplication.") 104 | return Vector(left.rows().map { Vector.dot($0, right) }) 105 | } 106 | 107 | static func dot(_ left: Matrix, _ right: Matrix) -> Matrix { 108 | assert(left.shape().columns == right.shape().rows, 109 | "Error in Matrix-Matrix Multiplication.") 110 | return Matrix(left.rows().map { leftRow in 111 | right.columns().map { rightColumn in 112 | Vector.dot(leftRow, rightColumn) 113 | } 114 | }) 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Posts/Promotion/Machine_Learning/Road_Map/1-Math-Linear_Algebra/Vector/Vector/Vector.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Vector.swift 3 | // Vector 4 | // 5 | // Created by kingcos on 2019/2/24. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Vector: CustomStringConvertible { 12 | 13 | private var values: [Double] 14 | 15 | var len: Int 16 | 17 | var description: String { 18 | return "Vector({\(values)}" 19 | } 20 | 21 | init(_ values: [Double]) { 22 | self.values = values 23 | len = values.count 24 | } 25 | 26 | static func zero(_ dim: Int) -> Vector { 27 | return Vector([Double](repeating: 0.0, count: dim)) 28 | } 29 | 30 | static func + (left: Vector, right: Vector) -> Vector { 31 | var left = left 32 | assert(left.len == right.len, 33 | "Error in adding. Length of vectors must be same.") 34 | 35 | right.values.enumerated().forEach { 36 | left.values[$0] += $1 37 | } 38 | 39 | return left 40 | } 41 | 42 | static func - (left: Vector, right: Vector) -> Vector { 43 | var left = left 44 | assert(left.len == right.len, 45 | "Error in subtracting. Length of vectors must be same.") 46 | 47 | right.values.enumerated().forEach { 48 | left.values[$0] -= $1 49 | } 50 | 51 | return left 52 | } 53 | 54 | static func * (left: Double, right: Vector) -> Vector { 55 | return Vector(right.values.map { $0 * left }) 56 | } 57 | 58 | static func * (left: Vector, right: Double) -> Vector { 59 | return right * left 60 | } 61 | 62 | func pos() -> Vector { 63 | return 1 * self 64 | } 65 | 66 | func neg() -> Vector { 67 | return -1 * self 68 | } 69 | 70 | func iter() -> IndexingIterator<[Double]> { 71 | return values.makeIterator() 72 | } 73 | 74 | func get(_ index: Int) -> Double { 75 | return values[index] 76 | } 77 | } 78 | 79 | extension Vector { 80 | static func / (left: Vector, right: Double) -> Vector { 81 | return 1 / right * left 82 | } 83 | 84 | func norm() -> Double { 85 | return sqrt(values.reduce(0) { $0 + $1 * $1 }) 86 | } 87 | 88 | func normalize() -> Vector { 89 | assert(norm() != 0, "Zero") 90 | 91 | return self / norm() 92 | } 93 | } 94 | 95 | extension Vector { 96 | static func dot(_ left: Vector, _ right: Vector) -> Double { 97 | var left = left 98 | assert(left.len == right.len, 99 | "Error in dot product. Length of vectors must be same.") 100 | 101 | right.values.enumerated().forEach { 102 | left.values[$0] *= $1 103 | } 104 | 105 | return left.values.reduce(0) { $0 + $1 } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/1/README.md: -------------------------------------------------------------------------------- 1 | # Studying - Effective Objective-C 2.0 2 | 3 | ## 1 - 熟悉 Objective-C 4 | 5 | ### 1. 了解 Objective-C 的起源 6 | 7 | - Obj-C 使用「消息结构」(Messaging Structure)而非「函数调用」(Function Calling) 8 | - 使用消息结构的语言,其运行时所应执行的代码由运行环境决定;而函数调用的语言,则由编译器决定 9 | - 多态 10 | - 函数调用的语言要按照「虚方法表」(Virtual Method Table),虚方法表是编程语言为实现「动态派发」(Dynamic Dispatch)或运行时「方法绑定」(Method Binding)而采用的一种机制 11 | - 消息结构的语言不论是否多态,总是在运行时才会去查找要执行的方法 12 | - 使用 Obj-C 的面向对象特性所需的全部数据结构及函数都在「运行期组件」(Runtime Component)里面 13 | - 运行期组件本质上就是一种与开发者所编代码想链接的「动态库」(Dynamic Library),其代码能把开发者编写的所有程序粘合起来;只需更新运行期组件,即可提升应用程序性能(而不需要重新编译代码) 14 | - Obj-C 是 C 的「超集」(Superset) 15 | 16 | ```objc 17 | // str:指向 NSString 的指针 18 | NSString *str = @"github.com/kingcos"; 19 | 20 | // ERROR: 21 | // 不能在「栈」(Stack)上分配 Obj-C 对象 22 | // Interface type cannot be statically allocated 23 | // NSString str = @"github.com/kingcos"; 24 | ``` 25 | 26 | - 对象所占内存总是分配在「堆空间」(Heap Space)上 27 | 28 | ```objc 29 | // str1 & str2 指向同一地址 30 | NSString *str1 = @"maimieng.com"; 31 | NSString *str2 = str1; 32 | ``` 33 | 34 | - `str1` & `str2` 两个变量都是 `NSString *` 类型,这说明当前栈帧(Stack Frame)里分配了两块内存,每块内存的大小都能容下一枚指针(32 位 4 字节,64 位 8 字节);这两块内存里的值都一样,存储了 NSString 实例的内存地址 35 | 36 | 37 | ### 2. 在类的头文件中尽量少引入其他头文件 38 | ### 3. 多要字面量语法,少用与之等效的方法 39 | ### 4. 多用类型常量,少用 #define 预处理指令 40 | ### 5. 用枚举表示状态、选项和状态码 -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/Effective_Obj-C_Demo/Effective_Obj-C_Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/Effective_Obj-C_Demo/Effective_Obj-C_Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/Effective_Obj-C_Demo/Effective_Obj-C_Demo/Computer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Computer.h 3 | // Effective_Obj-C_Demo 4 | // 5 | // Created by 买明 on 2019/3/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Computer : NSObject 14 | @property (copy) NSString *name; 15 | 16 | - (void)run; 17 | - (void)run:(NSString *)name; 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/Effective_Obj-C_Demo/Effective_Obj-C_Demo/Computer.m: -------------------------------------------------------------------------------- 1 | // 2 | // Computer.m 3 | // Effective_Obj-C_Demo 4 | // 5 | // Created by 买明 on 2019/3/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Computer.h" 10 | 11 | @implementation Computer 12 | - (instancetype)init 13 | { 14 | self = [super init]; 15 | if (self) { 16 | self->_name = @"COMPUTER"; 17 | } 18 | return self; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/Effective_Obj-C_Demo/Effective_Obj-C_Demo/Mac.h: -------------------------------------------------------------------------------- 1 | // 2 | // Mac.h 3 | // Effective_Obj-C_Demo 4 | // 5 | // Created by 买明 on 2019/3/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Computer.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Mac : Computer 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/Effective_Obj-C_Demo/Effective_Obj-C_Demo/Mac.m: -------------------------------------------------------------------------------- 1 | // 2 | // Mac.m 3 | // Effective_Obj-C_Demo 4 | // 5 | // Created by 买明 on 2019/3/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Mac.h" 10 | 11 | @implementation Mac 12 | - (void)setName:(NSString *)name { 13 | if (![name isEqualToString:@"Mac"]) { 14 | [NSException raise:NSInvalidArgumentException format:@"ERROR IN MAC."]; 15 | } 16 | self.name = name; 17 | } 18 | 19 | 20 | - (void)run { 21 | 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/Effective_Obj-C_Demo/Effective_Obj-C_Demo/MacPro.h: -------------------------------------------------------------------------------- 1 | // 2 | // MacPro.h 3 | // Effective_Obj-C_Demo 4 | // 5 | // Created by 买明 on 2019/3/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "Mac.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface MacPro : Mac 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/Effective_Obj-C_Demo/Effective_Obj-C_Demo/MacPro.m: -------------------------------------------------------------------------------- 1 | // 2 | // MacPro.m 3 | // Effective_Obj-C_Demo 4 | // 5 | // Created by 买明 on 2019/3/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import "MacPro.h" 10 | 11 | @implementation MacPro 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/Effective_Obj-C_Demo/Effective_Obj-C_Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Effective_Obj-C_Demo 4 | // 5 | // Created by kingcos on 2019/3/18. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import 12 | 13 | #import "objc-header.h" 14 | 15 | #import "Computer.h" 16 | #import "Mac.h" 17 | 18 | @interface Person : NSObject { 19 | int _age; 20 | } 21 | 22 | @property (readonly) int height; 23 | - (void)test; 24 | @end 25 | 26 | @implementation Person 27 | @synthesize height = ___height; 28 | //@dynamic height; 29 | - (void)test { 30 | // self->_height 31 | // self->_age 32 | // self->___height 33 | // self.height = 123; 34 | // self.height = 10; 35 | self->___height = 10; 36 | } 37 | 38 | @end 39 | 40 | int main(int argc, const char * argv[]) { 41 | @autoreleasepool { 42 | // insert code here... 43 | // NSLog(@"Hello, World!"); 44 | // // str1 & str2 指向同一地址;在当前栈帧(Stack Frame)里分配了两块内存,每块内存的大小都能容下一枚指针(32 位 4 字节,64 位 8 字节) 45 | ////// NSString *str1 = @"maimieng.com"; 46 | ////// NSString *str2 = str1; 47 | // Person *person = [[Person alloc] init]; 48 | //// person.height 49 | // [person test]; 50 | //// person.height = 10; 51 | // 52 | // 53 | //// objc_getClass(<#const char * _Nonnull name#>) 54 | // 55 | // NSObject *obj = [[NSObject alloc] init]; 56 | // object_getClass(obj); 57 | Mac *mac = [[Mac alloc] init]; 58 | 59 | } 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/Effective_Obj-C_Demo/Effective_Obj-C_Demo/objc-header.h: -------------------------------------------------------------------------------- 1 | // 2 | // objc-header.h 3 | // Effective_Obj-C_Demo 4 | // 5 | // Created by 买明 on 2019/3/19. 6 | // Copyright © 2019 kingcos. All rights reserved. 7 | // 8 | 9 | #ifndef objc_header_h 10 | #define objc_header_h 11 | 12 | //typedef struct objc_class *Class; 13 | 14 | //struct v_objc_object { 15 | //private: 16 | // isa_t isa; 17 | //}; 18 | // 19 | //struct v_objc_class : v_objc_object { 20 | // // Class ISA; 21 | // Class superclass; 22 | // cache_t cache; // formerly cache pointer and vtable 23 | // class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags 24 | // 25 | // class_rw_t *data() { 26 | // return bits.data(); 27 | // } 28 | //}; 29 | // 30 | // 31 | // 32 | 33 | 34 | 35 | 36 | 37 | #endif /* objc_header_h */ 38 | -------------------------------------------------------------------------------- /Posts/Studying/Effective_Objective-C_2.0/README.md: -------------------------------------------------------------------------------- 1 | # Studying - Effective Objective-C 2.0 2 | 3 | ## Info 4 | 5 | 名称 | 作者 | 版本 | 状态 6 | --- | --- | --- | --- 7 | Effective Objective-C 2.0 | Matt Galloway | 2014 | 0/52 8 | -------------------------------------------------------------------------------- /Posts/Studying/ICS_15-213/01-overview/README.md: -------------------------------------------------------------------------------- 1 | # Studying - ICS 15-213 Overview 2 | 3 | ## Preface 4 | 5 | 第一章概览,教授主要介绍了课程内容和安排等。 6 | 7 | ## Demo 8 | 9 | ```c 10 | #include 11 | #include 12 | 13 | int sq(int x) { 14 | return x*x; 15 | } 16 | 17 | // argc:命令行参数个数;argv[]:命令行参数数组 18 | int main(int argc, char *argv[]) { 19 | int i; 20 | for (i = 1; i < argc; i++) { 21 | int x = atoi(argv[i]); 22 | int sx = sq(x); 23 | printf("sq(%d) = %d\n", x, sx); 24 | } 25 | return 0; 26 | } 27 | ``` 28 | 29 | ```c 30 | #include 31 | #include 32 | 33 | typedef struct { 34 | int a[2]; 35 | double d; 36 | } struct_t; 37 | 38 | double fun(int i) { 39 | volatile struct_t s; 40 | s.d = 3.14; 41 | s.a[i] = 1073741824; /* Possibly out of bounds */ 42 | return s.d; /* Should be 3.14 */ 43 | } 44 | 45 | int main(int argc, char *argv[]) { 46 | int i = 0; 47 | if (argc >= 2) 48 | i = atoi(argv[1]); 49 | double d = fun(i); 50 | printf("fun(%d) --> %.10f\n", i, d); 51 | return 0; 52 | } 53 | ``` 54 | 55 | - `atoi` 56 | - 转换字符串为整型 57 | - `int atoi (const char * str);` 58 | - `volatile` 59 | - 告知编译器不做任何优化 60 | - 每次都从内存读取修饰的变量(不重复使用寄存器中的缓存) 61 | 62 | ## GDB 63 | 64 | ### Linux/Git Bootcamp 65 | 66 | > Use a Single Editor Well 67 | > 68 | > The editor should be an extension of your hand; make sure your editor is configurable, extensible, and programmable. 69 | > 70 | > —— [The Pragmatic Programmer](https://pragprog.com/the-pragmatic-programmer/extracts/tips) 71 | 72 | ## Words List 73 | 74 | monolithic 75 | tagline 76 | endeavor 77 | quirky 78 | entry 79 | evolve 80 | assumption 81 | profound 82 | rational number 83 | hypothesis 84 | bonkers 85 | wire 86 | effective 87 | mildly 88 | cornerstone 89 | revise 90 | retroactive 91 | apprise 92 | cheat 93 | plagiarism 94 | tempting 95 | obligation 96 | acquire 97 | vengeful 98 | mean 99 | instructor 100 | syllabus 101 | fairly 102 | relevant 103 | disclose 104 | queer 105 | statute 106 | interchangeable 107 | pseudocode 108 | fishy 109 | suspicious 110 | consequence 111 | penalty 112 | extenuating 113 | circumstance 114 | impose 115 | expulsion 116 | expel 117 | tremendous 118 | confess 119 | appeal 120 | unjust 121 | screw up 122 | procedure 123 | tutor 124 | extensive 125 | prompt 126 | bump 127 | rusty 128 | tweak 129 | duplex 130 | reveal 131 | boot camp 132 | mandatory 133 | shaky 134 | curriculum 135 | integrity 136 | infrastructure 137 | eliminate 138 | tune 139 | asymptotic 140 | presence 141 | arithmetic 142 | finiteness 143 | ring 144 | commutativity 交换性 145 | associativity 结合性 146 | distributivity 分配性 147 | monotonicity 单调性 148 | value of signs 奇偶性? 149 | flaw 150 | exploit 151 | unbounded 152 | dominated 153 | pernicious 154 | substance 155 | segmentation 156 | nasty 157 | asymptotic 158 | bottleneck 159 | modularity 160 | hierarchical 161 | critical 162 | autonomous 163 | coping 164 | portion 165 | incorporate 166 | parallel 167 | capstone 168 | imperative 169 | verbal 170 | semester 171 | ignorance 172 | asap 173 | sophisticated 174 | expelled 175 | desperate 176 | panic 177 | frustration 178 | frustrate 179 | guilt 180 | penalize 181 | disciplinary 182 | burden 183 | betrayal 184 | scenario 185 | constitute 186 | sustained 187 | logistics 188 | appointment 189 | rack 190 | crunch 191 | catastrophic 192 | defusing 193 | multiplexing 194 | rationale 195 | writeup 196 | faculty 197 | 198 | ## Reference 199 | 200 | - [`atoi`](http://www.cplusplus.com/reference/cstdlib/atoi/) 201 | - [`volatile`](http://tigcc.ticalc.org/doc/keywords.html#volatile) 202 | - [C 语言再学习 -- 关键字 volatile](https://blog.csdn.net/qq_29350001/article/details/54024070) 203 | - [GDB](http://www.sourceware.org/gdb/) 204 | - [The Pragmatic Programmer](https://pragprog.com/the-pragmatic-programmer/extracts/tips) 205 | - [Resources to learn Git](http://try.github.io) 206 | - [Become 207 | a git guru.](https://www.atlassian.com/git/tutorials) 208 | -------------------------------------------------------------------------------- /Posts/Studying/ICS_15-213/02-bits_bytes_integer_i/README.md: -------------------------------------------------------------------------------- 1 | # Studying - ICS 15-213 Overview 2 | 3 | ## Preface 4 | 5 | ## Words List 6 | 7 | monolithic 8 | tagline 9 | endeavor 10 | quirky 11 | entry 12 | evolve 13 | assumption 14 | profound 15 | rational number 16 | hypothesis 17 | bonkers 18 | wire 19 | effective 20 | mildly 21 | cornerstone 22 | revise 23 | retroactive 24 | apprise 25 | cheat 26 | plagiarism 27 | tempting 28 | obligation 29 | acquire 30 | vengeful 31 | mean 32 | instructor 33 | syllabus 34 | fairly 35 | relevant 36 | disclose 37 | queer 38 | statute 39 | interchangeable 40 | pseudocode 41 | fishy 42 | suspicious 43 | consequence 44 | penalty 45 | extenuating 46 | circumstance 47 | impose 48 | expulsion 49 | expel 50 | tremendous 51 | confess 52 | appeal 53 | unjust 54 | screw up 55 | procedure 56 | tutor 57 | extensive 58 | prompt 59 | bump 60 | rusty 61 | tweak 62 | duplex 63 | reveal 64 | boot camp 65 | mandatory 66 | shaky -------------------------------------------------------------------------------- /Posts/Studying/ICS_15-213/README.md: -------------------------------------------------------------------------------- 1 | # Studying - ICS 15-213 2 | 3 | ## Info 4 | 5 | 名称 | 作者 | 版本 | 状态 6 | --- | --- | --- | --- 7 | Introduction to Computer Systems | CMU | Fall 2017 | 1/33 8 | 9 | ## List 10 | 11 | - [Overview](01-overview) 12 | - [Bits, Bytes, & Integers I](02-bits_bytes_integer_i) 13 | 14 | ## Reference 15 | 16 | - [15-213/18-213/15-513: Introduction to Computer Systems (ICS)](http://www.cs.cmu.edu/afs/cs/academic/class/15213-f17/www/index.html) 17 | - [Computer Systems: A Programmer's Perspective, Third Edition](http://csapp.cs.cmu.edu/) 18 | - [ICS 15-213 Fall 2017 Video - Bilibili](https://www.bilibili.com/video/av20304787) -------------------------------------------------------------------------------- /Posts/Studying/MacOSX_and_iOS_Internals/README.md: -------------------------------------------------------------------------------- 1 | # Studying - Mac OS X and iOS Internals 2 | 3 | ## Info 4 | 5 | 名称 | 作者 | 版本 | 状态 6 | --- | --- | --- | --- 7 | Mac OS X and iOS Internals | Jonathon Levin | 2013 | 0/828 8 | 9 | ## Reference 10 | 11 | - 中文版:《深入解析 Mac OS X & iOS 操作系统》(清华大学出版社) -------------------------------------------------------------------------------- /Posts/Studying/Programming_from_the_Ground_Up/README.md: -------------------------------------------------------------------------------- 1 | # Studying - Programming from the Ground Up 2 | 3 | ## Info 4 | 5 | 名称 | 作者 | 版本 | 状态 6 | --- | --- | --- | --- 7 | Mac OS X and iOS Internals | Jonathon Levin | 2013 | 0/828 8 | 9 | ## Reference 10 | 11 | - [Programming from the Ground Up Book - Summary](http://savannah.nongnu.org/projects/pgubook/) 12 | -------------------------------------------------------------------------------- /Posts/Studying/WWDC/2017/102/README.md: -------------------------------------------------------------------------------- 1 | # Studying WWDC 2017 - 102 Platform State of the Union 2 | 3 | | Date | Notes | Swift | Xcode | 4 | |:-----:|:-----:|:-----:|:-----:| 5 | | 2017-07-02 | 首次提交 | 4.0 beta | 9.0 beta| 6 | 7 | > WWDC 2017 是苹果开发者大会的 2017 版,今年的更新很多,而且涉及多种平台,开发工具,以及 Swift 语言本身。102 这场演讲涉及了新系统以及新工具中的 features,但没有过多深入。因为后续还有更加独立的 Session 可供我们学习,查看,所以本文仅涉及本人认为需要的内容。关于 Metal 2 和 VR 距离我个人能力所及较远,本文也没有提及。 8 | 9 | ## macOS 10 | 11 | - macOS High Sierra 将是最后一个支持 32 位程序的 macOS 版本。 12 | - App Store 64 位 App: 2018.01 新 App 务必支持;2018.07 所有 App 务必支持。 13 | 14 | ## Playground 2.0 15 | 16 | - 将集成 API 文档,且支持 AR。 17 | 18 | ## Xcode 9 19 | 20 | - 支持 Swift,Objective-C,C/C++ 重构。 21 | - 构建速度加快,打包后体积更小。 22 | 23 | ## String 24 | 25 | - String 在 Swift 4.0 中已改为集合类型(Collection)。 26 | 27 | ```Swift 28 | // String 是 Character 的集合 29 | var s = "Hello!" 30 | for c in s { 31 | print(c) 32 | } 33 | 34 | s.last == "!" 35 | s.index(of: "!") 36 | 37 | s.dropLast() + " world!" 38 | 39 | // 多行字符串字面量 40 | let html = """ 41 | 42 | 43 | 44 | Demo 45 | 46 | 47 |

Test multi-line string literals.

48 | 49 | 50 | """ 51 | 52 | let gtIndex = html.index(of: ">")! 53 | let substring = html[...gtIndex] 54 | 55 | // Unicode 9 Grapheme Breaking 56 | "👩‍👩‍👧‍👦".count == 1 57 | ``` 58 | 59 | ## Codable 60 | 61 | ```Swift 62 | // Codable 是 Decodable & Encodable 的别名 63 | // A type that can convert itself into and out of an external representation. 64 | // public typealias Codable = Decodable & Encodable 65 | 66 | struct Location: Codable { 67 | var latitude: Double 68 | var longitude: Double 69 | } 70 | 71 | enum Animal: Int, Codable { 72 | case cow = 0 73 | case dog = 1 74 | case chicken = 2 75 | } 76 | 77 | struct Farm: Codable { 78 | let name: String 79 | let location: Location 80 | let animals: [Animal] 81 | } 82 | 83 | let farm = Farm(name: "Kingcos' Farm", 84 | location: Location(latitude: 1.0, 85 | longitude: 1.0), 86 | animals: [.cow, .dog, .chicken]) 87 | 88 | // -> JSON 89 | let payload: Data = try JSONEncoder().encode(farm) 90 | print(String(data: payload, encoding: .utf8) ?? "nil") 91 | 92 | // JSON -> 93 | let farmFromJSON = try JSONDecoder().decode(Farm.self, from: payload) 94 | farmFromJSON.location.latitude 95 | ``` 96 | 97 | ## Swift 3.2 vs Swift 4.0 98 | 99 | - Swift 3.2 兼容旧项目,不需要修改即可构建。 100 | - Swift 3.2 不包含 Swift 4.0 中对现有 API 的改进。 101 | 102 | ## Drag & Drop 103 | 104 | - 此处代码摘自视频,未经测试。 105 | 106 | ```Swift 107 | // Begin Drag 108 | let dragData = self.data(at: sourceIndexPath) 109 | let itemProvider = NSItemProvider(object: dragData) 110 | return [UIDragItem(itemProvider: itemProvider)] 111 | 112 | // Perform Drop 113 | coordinator.session.loadObjects(ofClass: MyDataType.self) { (data) in 114 | self.insertData(data, at: destinationIndexPath) 115 | collectionView.reeloadSections(IndexSet(integer: 0)) 116 | } 117 | ``` 118 | 119 | ## Large Titles 120 | 121 | - 此处代码摘自视频,未经测试。 122 | 123 | ```Swift 124 | // Adopt Large Titles 125 | navigationBar.prefesLargeTitles = true 126 | 127 | // Automatically Choose Large Title 128 | navigationItem.largeTitleDisplayMode = .automatic 129 | 130 | // Adopt Unified Search Bar 131 | navigationItem.searchController = searchController 132 | ``` 133 | 134 | ## HEVC & HEIF 135 | 136 | - 新的视频和图片压缩编码标准。 137 | - 此处代码摘自视频,未经测试。 138 | 139 | ```Swift 140 | // 在不支持新标准的平台播放可加入以下判断 141 | var asset = AVAsset(url: URL(fileURLWithPath: "hevc.mov")) 142 | if !asset.isPlayable { 143 | asset = AVAsset(url: URL(fileURLWithPath: "h264.mov")) 144 | } 145 | 146 | 147 | let url = URL(string: "")! 148 | CIImage(contentsOf: url, options: [kCIImageAuxiliaryDepth: true]) 149 | ``` 150 | 151 | ## Machine Learning 152 | 153 | ![Machine Learning](img/1.png) 154 | 155 | ## ARKit 156 | 157 | ![ARKit](img/2.png) 158 | 159 | ## Reference 160 | 161 | - [WWDC 17 - 102 Platforms State of the Union](https://developer.apple.com/videos/play/wwdc2017/102/) -------------------------------------------------------------------------------- /Posts/Studying/WWDC/2017/102/img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Studying/WWDC/2017/102/img/1.png -------------------------------------------------------------------------------- /Posts/Studying/WWDC/2017/102/img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Studying/WWDC/2017/102/img/2.png -------------------------------------------------------------------------------- /Posts/Studying/WWDC/2017/819/README.md: -------------------------------------------------------------------------------- 1 | # Studying WWDC 2017 - 819 Designing for a Global Audience 2 | 3 | | Date | Notes | 4 | |:-----:|:-----:| 5 | | 2017-07-03 | 首次提交 | 6 | 7 | > WWDC 2017 是苹果开发者大会的 2017 版。Session 822 简要介绍了为什么要将 App 为全球受众适配,以及其中的一些注意点。 8 | 9 | ## Why 10 | 11 | - 更好的用户体验(Better user experience) 12 | - 不要仅仅止步于言语和插图不冒犯用户。 13 | - 拓展机遇(Expansion opportunities) 14 | 15 | ## How 16 | 17 | - 制定计划(Make a plan) 18 | - 制定下一个将要适配的国家和语言,可以参考 iTunes Connect 中的一些信息。 19 | - 识别用户(Identify users) 20 | - 考虑交流(Think about communication) 21 | - 重要优先(Prioritize important localization work) 22 | 23 | ## 语言 24 | 25 | - 替代语(Substitutions) 26 | - 部分翻译(Partial translation) 27 | - 头部,标题(Headings, titles) 28 | - 关键性的指导(Critical instructions) 29 | - 关键词(Keywords) 30 | - 错误信息(Error messages) 31 | - 非正式用语(Informal language) 32 | - 俚语(Slang) 33 | - 修辞比喻(Figures of speech) 34 | 35 | ## 符号 36 | 37 | - 手势(Gestures) 38 | - 巨大的差异(Wide variation) 39 | - 比如不同文化区域用手数 1、2、3 的手势就有很大差异。 40 | - 本地化与国际化(Localized vs. globalized) 41 | - 特定化与普遍化(Specific vs. universal) 42 | - 联系(Associations) 43 | 44 | ## 参考资源 45 | 46 | - 旅行(Travel) 47 | - 讨论组(Focus groups) 48 | - 私人和专业联系人(Personal and professional contacts) 49 | - 语言、翻译、旅游论坛(Language, translation, travel forums) 50 | - 网络、图片搜索(Web and image searches) 51 | - 论文著作(Publications) 52 | - 图书馆(Libraries) 53 | 54 | ## Reference 55 | 56 | - [WWDC 17 - 819 Designing for a Global Audience](https://developer.apple.com/videos/play/wwdc2017/819/) 57 | -------------------------------------------------------------------------------- /Posts/Studying/WWDC/2017/822/README.md: -------------------------------------------------------------------------------- 1 | # Studying WWDC 2017 - 822 App Icon Design 2 | 3 | | Date | Notes | 4 | |:-----:|:-----:| 5 | | 2017-07-03 | 首次提交 | 6 | 7 | > WWDC 2017 是苹果开发者大会的 2017 版。Session 822 简要介绍了设计 App 的图标(Icon)时需要注意的点。 8 | 9 | ## 图标设计 10 | 11 | - 象征(Metaphor) 12 | - 即人们可以根据图标所联想的事物。 13 | - 简约(Simplicity) 14 | - 清晰简约,可读性强。 15 | - 连接(Connection) 16 | - 图标是用户和应用的桥梁,要有趣,有启发性。 17 | - 家系(Lineage) 18 | - 图标的改变要慎重,有一致性。 19 | 20 | ## 设计过程 21 | 22 | - 唯一(Unique) 23 | - 在应用的分类中脱颖而出。 24 | - 体验(Experiment) 25 | - 开始可以手绘,也可以与他人共同体验。 26 | - 测试(Test) 27 | - 在桌面,文件夹,设置中测试图标的效果。 28 | - 耐心(Patience) 29 | 30 | ## Reference 31 | 32 | - [WWDC 17 - 822 App Icon Design](https://developer.apple.com/videos/play/wwdc2017/822/) 33 | -------------------------------------------------------------------------------- /Posts/Studying/WWDC/2017/823/README.md: -------------------------------------------------------------------------------- 1 | # Studying WWDC 2017 - 823 Designing Glyphs 2 | 3 | | Date | Notes | 4 | |:-----:|:-----:| 5 | | 2017-07-02 | 首次提交 | 6 | 7 | > WWDC 2017 是苹果开发者大会的 2017 版。Session 823 简要介绍了 Glyph(字形,符号等)的设计原则等。 8 | 9 | ## Glyph & Icon 10 | 11 | - Glyph 是单色的,可以用代码(程序化)添加颜色。 12 | - Icon 是彩色的,高渲染的资源文件。 13 | 14 | ## 高效的 Glyph 设计原则 15 | 16 | - 简化的形式(Simplified form) 17 | - 统一的象征(Universal symbology) 18 | - 在不同的语言环境,生活环境都能清晰无歧义辨识的标志 19 | - 上下文中可读性高(Quickly readable in context) 20 | 21 | ## Glyph 在系统中的使用场景 22 | 23 | - macOS 24 | - Menu bars 25 | - Tool bars 26 | - Touch bar 27 | - iOS 28 | - Tab bars 29 | - List views 30 | - Quick menu (3D Touch) 31 | - 要比应用内部更大且更重 32 | 33 | ## Glyph 的设计考量 34 | 35 | - 视觉重心(Optical weight) 36 | - 表面区域较小的 Glyph 可以缩放来达到视觉平衡。 37 | - 线条(Lines) 38 | - 线宽(Line weight)一致化。 39 | - 位置(Positioning) 40 | - 以视觉居中为主。 41 | 42 | ## 制作原则 43 | 44 | - 按一个集合来做(Build as a set) 45 | - 上下文中测试(Test in context) 46 | - 在设备中预览(Preview on device) 47 | 48 | ## Reference 49 | 50 | - [WWDC 17 - 823 Designing Glyphs](https://developer.apple.com/videos/play/wwdc2017/823/) 51 | -------------------------------------------------------------------------------- /Posts/Thought/180625/README.md: -------------------------------------------------------------------------------- 1 | # Thought - 胡言乱语 2 | 3 | ## 环境 or 格局 4 | 5 | 自从读大学以来,我一直能够深刻感受到环境的重要性。当一个人内心拥有改变自我的决心时,往往会忽略环境,可能会认为尽最大努力就能突破个人极限,达到自己的目标。但正如「温水煮青蛙」,有些时候不能太看中个人努力,而要尽可能突破身处的环境,看到更大的世界,这可能就是「格局」。移动互联网给了我们机会,信息的传递已经接近了光速,但信息的产生却仍然依赖其本身的规律,突破了时间却无法突破地域。 6 | 7 | 我在本科的时候,所体会到的环境,可以说只是一种学习环境。当时的我认为,学校的班级、社团无法提供一个积极、先进的环境时,便开始自学。虽然我学的资料大部分是国内较好学校的公开课,抑或国外名校开的 Mooc,但我的眼光仍然局限在我的专业所在。所以相较于其他同学来说,可能只是在知识的掌握度上会更好一些,但其实我们所学的东西,本质上仍然是一样的。当我在大三暑假,去了上海,待了三个月之后有幸参加复旦的一场比赛时,才真切地感受到另外一种环境。当我们还在写网站、搞 App 时,相对前沿的大学已经开始 Machine Learning、AI、Block Chain、AR/VR... 我不去评判这些具体的技术是否是噱头,真正能活跃多久,以及是否就优越于做普通的工程开发。但我已经深刻体会到这种环境对个人格局产生的巨大差异化。所以在后来多次参加类似比赛时,每次也都能感受到类似的问题。 8 | 9 | 今天看了一小段马云的视频,当然我个人不是他的粉。但看到的这段说的也确实有一些道理:当你考试能达到 90 分的时候,已经很优秀了,那么就不应该再去局限在这个离满分只有 10 分的科目了,而应该把时间用在其他能够更大限度提升的科目中。 10 | 11 | 所以,能够跳出自身局限,看到未来的格局,也并不需要每个人都拥有。但若你想有所作为,想要「颠覆」,那么这点格局观可能还是要有一些。 12 | 13 | ## 巨头 and 创业 14 | 15 | 随着很多行业发展趋于停滞甚至倒退,而信息技术却仍然有澎湃的发展速度。火到各大高校竞相开设人工智能学院的 AI,到炒币割韭菜的区块链,从各大直播,到抖音、快手的短视频,再到即将到来的 5G,信息技术似乎仍然以高速向前发展。而我们就身处这个行业,见证着发展,也算是幸运的。但在国内,各种巨头化,也非常明显。这些巨头掌握了大量的流量、人才、资金,似乎就是一种强者更强,弱者更弱的循环。当然,蛋糕也不可能完全被巨头瓜分,创业者们也有不少机会,但国内的创业环境还是比较艰难且浮躁的。上有巨头,下有不按套路出牌,就想捞一票就走人的搅局者。 16 | 17 | 从今天的角度回看乔布斯当年谈及营销时所说的,当产品做到一定程度时,可能就很难再去优化。而这个时候广告等业务可能就会因为 KPI 出众而被重用,慢慢就偏离了打造好的产品的初衷,而技术就变得不再受重视,公司就不再乐意去投资未来。 18 | 19 | 虽然现在国内整体的创业环境真的很浮躁,房价也让人人心惶惶(房产大于实业)。但一款好产品,确实需要时间来打磨。但好产品就真的能「畅销」吗?这可能还需要一些运气或者机遇。所以,真正怀揣着「Change the world」心态的创业者还是需要一些理想主义。 20 | 21 | 创业维艰。 22 | 23 | > 作于 2018 年 6 月 25 日凌晨,北京。 -------------------------------------------------------------------------------- /Posts/Thought/180706/README.md: -------------------------------------------------------------------------------- 1 | # Thought - 胡言乱语 2 | 3 | ## 培训机构是原罪? 4 | 5 | 每隔一段时间,培训机构都要被放在 V2EX 上「讨伐」一次。我虽然没有参加过真正的培训机构,但也不否认曾经看过「黑马」、「传智播客」等课程,也在网上学习过各种 Mooc 和公开课,身边的同学也有参加过培训机构的。所以我也时常会回复这些「讨伐」的帖子,当然,论坛是交流,写在这里,则是一种记录。 6 | 7 | 首先,我想明确对培训机构的态度。培训机构从出现,到百家争鸣,它的存在一定是有市场理由的。如果毕业的学生大多数都找不到工作,那么其本身存在的意义就不那么大了。培训机构和现在很多的知识付费有一定的区别,培训机构的目的性非常强,目的是为了找工作。而知识付费大多是为了已经进入职场的人或者学生,补充知识和技能的方式。所以动辄上万,持续四五个月的培训机构仍能招揽一批接一批的学生。所以对于其目的,我认为培训机构存在的合理性,没有质疑。从我身边的例子也能看出来,培训机构确实为不少没有背景,没有一技之长,甚至还没有找到人生方向的同学们,解决了第一份工作的问题。所以我个人对培训机构的整体态度是肯定的。 8 | 9 | 当然,有很多人提到培训机构就嗤之以鼻。尤其可能是一些稍大厂的 HR,或者有些发自内心热爱开发的工程师,他们看到简历中有类似培训的经历,就会一票否决。那么,培训机构真的就那么不行吗? 10 | 11 | 据我了解,很多本科为二三本,甚至一本的同学,不考虑升学、考公,但又在大学玩了四年,临近毕业看了培训机构的「高薪」广告宣传,便报名了各种培训机构,集中学习四个月,再步入工作岗位。 12 | 13 | 如果是计算机科学或软件工程相关专业,国内刚本科毕业的大学生,就我所了解到,其实并不一定比培训机构集中式所教育的学生高。首先,因为培训机构的目的性非常强,目的即是找到工作,而大学生压力不大,有时是出于自己兴趣,有时是出于完成作业。其次,培训机构相对比较「系统」和「专一」。大学中的计算机科学或软件工程专业课,很多是偏基础和理论的,而培训机构为的是工作,因此其培训的内容大多是工作中所接触到的内容。理论知识,算法等,培训机构会专门把这些内容作为应对面试的内容教授给学生。这些内容重要还是具体实践重要呢?其实都很重要,只是出于目的,侧重不太一样罢了。最后,培训是一个短期的持续过程,比放寒暑假的大学生活紧凑的多,培训又是从早上到晚,一周多达六天。任何大学都不可能做到这样的排课率。那按理说似乎培训又占据了优势?其实上面的条件都是外在的,忽视了人的内在兴趣。人都是趋利避害的,真正有兴趣的事情才能得以坚持。即是为了「高薪」委屈求全上了培训,但如果从内心就是抵触计算机,那他绝对不会在程序开发的这条路上走得太远。 14 | 15 | 16 | 曾经有个要考研的女同学问我,计算机就业哪个方向不需要敲代码呢?我说不可能完全不接触到代码。即使有岗位可以不依赖程序开发,那么会代码也是一个加分项。问问很多程序员就可以了,他们是多么得希望产品经理能了解一点程序开发。 17 | -------------------------------------------------------------------------------- /Posts/Thought/180715/README.md: -------------------------------------------------------------------------------- 1 | # Thought - 胡言乱语 2 | 3 | ## iOS 开发没人要了? 4 | 5 | 「iOS 开发没人要了」,这句话,以及相应的表情包已经在很多 iOS 开发的社群、媒体上传开了。大家总是拿这个当作调侃,那么 iOS 开发的行情到底如何?iOS 开发的未来将如何发展?却似乎比较少提及讨论。 6 | 7 | 如果单独看 iOS 开发,那么这就和 Apple 公司及其产品息息相关。毫无疑问,iPhone 和 iPad 在移动互联网高速发展的进程中高飞猛涨。虽然销量偶有起伏,但 Apple 的利润却连年增长。纵使国内媒体如何渲染 Apple 没有创新,国内手机厂商如何发布会吊打 iPhone,Apple 的领导地位仍不容置疑,所以,Apple 暂时不会完。Apple 不会完,那 iOS 开发呢? 8 | 9 | 众所周知,Apple 在 2014 年正式公布了新的开发语言,Swift。经过前两年的大修大改,进入了现在精雕细琢的阶段。iOS 开发者除了要会以前的 Obj-C 来兼容就代码,又要积极自学 Swift,以防未来掉队。Swift 成熟了吗?至今还没有,加上和 C/C++ 的兼容性远不如 Obj-C,很多老旧项目无法很快得切入 Swift。欣慰的是很多厂商已经在这个过程中慢慢过渡。即混编状态,我司也不例外。 10 | 11 | 迫于 Swift 只利于开发 Apple 下各种设备的平台,很多大厂就在尝试 React Native 等跨平台技术。 12 | -------------------------------------------------------------------------------- /Posts/Thought/180727/README.md: -------------------------------------------------------------------------------- 1 | # Thought - 人生の目覚める 2 | 3 | 为什么突然用日语当标题了呢?是因为我突然想起「觉醒」这个词,感觉其日语似曾相识。 4 | 5 | 有时候我总能想起一些人生的觉悟,但迫于没有记录,时常总是后知后觉。所以从现在起,我就尽量将其记录于此,提醒自己。 6 | 7 | - 180727 8 | - 切莫**交浅言深**; 9 | - 物质是必需的,但不是首要因素;世俗是不可避免的,但不要忘记**初心**; 10 | - 180728 11 | - 有些东西确实很有搞头,能够获得一时的成就感,但其实对整个过程并没有太大的帮助。如果有时间,自然可以「折腾」,但时间很紧迫的时候,一定要把时间和精力放在更**专注**的地方; 12 | - **专注可贵,坚持亦可贵;** 13 | - 180729 14 | - 外在是极度不可控的,因此要靠**内在**去改变,但也要**感知到外在**; 15 | - 180730 16 | - 拼多多上市之后,有些人公布了很多数据,大致是国内只要努力到 XX 程度,就能超越 YY % 的人。无论这些数据是否真实,但确实很多时候,环境蒙蔽了我们的双眼。即使互联网的传播速度已经非常迅速了,**但同步的「速度」却远远落后**,似乎就像一种「延迟」。常常发现很多模式都是从大城市试验成功之后,再被搬到了小城市; 17 | - 有时候超越并不难,**多迈出一步**,就能超越很多人。所以每当走不下去的时候,想想吧,如果自己是迈出步伐的人,就领先了; 18 | - 与其把时间浪费在纠结买贵的还是便宜的产品上,不如直接买下贵的产品,再让其物超所值,**发挥其作用**; 19 | - 不要把时间浪费在后悔上,因为过去已经无法改变,**为什么不把时间努力在让未来少后悔上呢**; 20 | - 180906 21 | - 其实能观察到很多小型创业的店面,在只有一家店的时候,经营非常不错。而当其扩张之时,开了分店,却走了下坡路。太过于理性的事物做多了,有时就会忽略感性。管理并非简单地指挥,而是确实有学问在其中。 22 | - 在小型团体内部的管理中,威信的树立非常重要。能够以能力服人其实是最简单的,而各种日常事务的安排,与团队每个人之间的沟通却更为重要。切忌朝令夕改,或是因为个人原因忽视团队中的人员。 23 | -------------------------------------------------------------------------------- /Posts/Thought/180805/README.md: -------------------------------------------------------------------------------- 1 | # Thought - 100 個基本 2 | 3 | 今天偶然间走进了一家书店,在畅销书中摆着几本《100 个基本》,便随手翻看了起来。对其中的内容倒不是非常印象深刻,而是挺喜欢这种形式:书中一页简单写着一句基本信条,而另一页简单地阐述了对其的思考。 4 | 5 | 正如松浦弥太郎这些基本,我们也可以简单地树立自己的信条,不断遵守,不断修正,不断美好。 6 | 7 | - **001. 每天早上,备一份早餐,开始一天;每天晚上,读几页书,结束一天。** 8 | 9 | > 生活中不是所有事情,都必须要有意义。正如吃了饭总会饿,读了书总会忘,人活着总会死。所以,面对生活也说一句「いただきます(我要开动啦)」吧~ 10 | 11 | - **002. 提前一点,而不是推迟一点。** 12 | 13 | > 熬夜、晚起,有时候其实并不是「生物钟」,而是习惯了推迟、拖延。不要等待,不要犹豫,任何事情都提前一点,做好准备吧,该来的总会来,不如迎头赶上呢~ -------------------------------------------------------------------------------- /Posts/Thought/181210/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Thought/181210/1.png -------------------------------------------------------------------------------- /Posts/Thought/181210/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Thought/181210/2.jpg -------------------------------------------------------------------------------- /Posts/Thought/181210/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Thought/181210/3.jpg -------------------------------------------------------------------------------- /Posts/Thought/181210/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Thought/181210/4.jpg -------------------------------------------------------------------------------- /Posts/Thought/181210/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Thought/181210/5.jpg -------------------------------------------------------------------------------- /Posts/Thought/181210/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Thought/181210/6.jpg -------------------------------------------------------------------------------- /Posts/Thought/181210/README.md: -------------------------------------------------------------------------------- 1 | # Thought - 2018 年「终」总结 2 | 3 | 今天是 2018 年 12 月 10 日,一年前的昨天,我从家里坐高铁到达了北京。还记得那天晚上,两个同学来火车站接我,我们一起坐公交去他们在昌平沙河的培训宿舍。一天的奔波加上本来就晕车的我,在公交行驶过高速后就难受的不行,不得不下车休息片刻。 4 | 5 | 不像刚到上海的时候,没有工作的压力,充满着一些生活的气息。而来到北京就是为了实习,为了工作。虽然目的性更强,但也让我不得不更快地融入这个环境,而没时间去慢慢感受。我是北方人,北京更加令我熟悉,但却总感觉不如上海能带给我的新鲜感。从在北科的宿舍到确定现在住的地方,我一共搬了四次家,最终选择了公司附近但价格相对较高的房间。虽然房租已经逼近当时我的实习工资,但这一年我认为这个投资还是非常值得的,毕竟时间的价值更难以衡量。 6 | 7 | ![Google Photos](1.png) 8 | 9 | 在北京实习的日子里,去北大参加了比赛,又回到学校拍了毕业照,再辗转到长沙比赛,又去武汉听了音乐会,回了趟家,最后又返回了北京,正式加入了现在的团队。 10 | 11 | 在北大的比赛,让我感受到我和这些名校学生的差距并没有想象中的遥不可及,当然我不是说差距不明显而是觉得自己有了信心。当然我也羡慕他们拥有如此丰富的资源,也坚定了我会再去读研的决心。虽然比赛最后的名次并不是很靠前,但和北大学长学姐、北航浙大学弟的这次友谊和合作,令我倍感幸运。 12 | 13 | ![XiYue Award](2.jpg) 14 | 15 | 北大比赛结束的第二天,我便一早乘坐高铁回学校,准备再见见大学的同学们,拍拍毕业照。班长为了等我,特意将聚餐时间往后推迟了一日。所以很遗憾有些同学因为工作等原因提早回去,只得有缘再见。在大学的四年里,我担任学委,和大学同学们的相处甚至要好过于高中同学。当然,不得不说毕业聚餐后发生了一些事情,也许是这辈子都不会忘记的事情吧...虽然学校只是个很普通的二本,这四年也发生了很多事情,但一些老师和这些同学们却让我不后悔来到这里。 16 | 17 | ![Celebrate](3.jpg) 18 | 19 | 要想放下一些事情,就得让自己忙起来。忙完大学生涯最后的篇章,便又启程去了长沙,这次的比赛地点是在长沙的超算中心。说实话,这次的比赛因为没有很好的构思,只能很简单地做了个 Demo,效果也非常一般。这次的比赛是面向华中地区,相较于在上海和北京的比赛,能明显感受到一些差距,但也越发发现这类比赛的作品其实存在着很高的重复性。最后因为赶音乐会的时间紧迫,没能在长沙逗留一段时间,仅有的一丝印象也是一座非常干净、轻松的城市。 20 | 21 | ![Changsha](4.jpg) 22 | 23 | 离开长沙,坐上高铁,奔向武汉。去武汉的理由很简单,只是在复旦比赛认识的队友多买了一张音乐会的票,于是就随他去了。因为通宵比赛,加上路途奔波,我已经非常疲倦,但这次音乐会对于我个人感受至深。我们还年轻,生活不应该只是对着电脑、手机,生活纵然有不易,但也是如此的丰富多彩。也没有来得及注意武汉,但确实也是一座非常发达的城市。 24 | 25 | ![Qintai Concert Hall](5.jpg) 26 | 27 | 享受完音乐会,便又马不停蹄地踏上回家之途。其实原本打算是直接回北京,但想到工作之后回家似乎就不那么自由,便还是决定回家一趟。出门久了才知道,什么都抵挡不过父母做的一顿饭,只是这次在家呆不了太久,便又要踏上北上之途。 28 | 29 | ![Delicious](6.jpg) 30 | 31 | 回京之旅和以往不同,是因为买到了比高铁还要便宜的机票,人生中第一次乘坐了飞机。可能洛阳坐飞机的人并不多,飞机也并没有我想象中那么大,不过飞机起飞加速时的推背感却让我感到很过瘾。 32 | 33 | 这一年真的是非常丰富的一年,除了上面这一段游记,年初的时候在北京陪韩国留学放假回来的好友在北京玩了几天,看了升旗,逛了故宫,也了解了航天与航空的差异(笑);在北京去了 Apple Store,和北京的小朋友一起上了 Today at Apple,感受了苹果新的零售哲学;六月中旬去了清华,和来上科大宣讲的外籍教授一对一讨论了 Robotistic(机器人学),也认识了上科大优秀的博士生;第一次正式加入一家公司;主动和团队里的人去美团总部交流技术;在新员工培训中拿到了第一名;周末和同学第一次爬了长城;第一次被拉去蹦了野生迪... 34 | 35 | 当然,一年再怎么精彩,也依然会有遗憾。对于那些可以在未来弥补的遗憾,就放在之后的计划中吧,对于那些无法弥补的,就让它过去吧。感谢 2018 年,也感谢这一年遇到的所有人,辗转多地也遇到很多可爱的人。最后,也感谢自己。幸运,总是留给有准备的人。2019,加油! 36 | 37 | *V.* 38 | 39 | *提笔于 2018.12.10,完结于 2018.12.11 晚;北京* 40 | 41 | --- 42 | 43 | ## 后记 44 | 45 | 原本以为 2018 年就会如此过去,却没曾想到在最后一周又发生了很多事情。倒数第二周的周末,听闻公司「优化」的消息,又一次下载了脉脉。传言言之凿凿,又加上我还未转正,简直是「性价比」之选。其实工作了一年,确实感觉辛苦,不如学生时代的自由和悠闲。虽然有了所得,但失去的更多。所以如果被「优化」,我就准备先回学校把驾照考完,再去想想自己真正热爱的事情,其实我一直有想法要亲自打造一款产品,那么我想就是时候去做了。 46 | 47 | 当然,结果是我并没有被「优化」,打造产品的计划又被耽搁了,而让我痛心的是和我一起入职的好几个小伙伴们被「优化」。工作这一年,越发认识到社会上的人久而久之都会变得「油腻」,而这些刚从校园里出来的孩子们却没有社会上的浮躁气息,失去这些同事实在令我可惜。真心希望他们能找到更好的去处,也希望我们友谊长存,也希望我自己能保持初心。 48 | 49 | 2018 年从实习,到公司被收购,入职,涨薪,裁员,这些经历都让我学习到很多。其实这种「优化」和个人能力的相关性很低,而和个人所在的业务关联性很大。之前总是天真地以为技术是唯一,其实现在才发现,技术只是基本功,个人的能力绝不能仅仅只在技术能力上体现,而是需要全方位的修炼。 50 | 51 | 2018 年总归要过去,虽然在 2018 年的尾巴上又重新加回了一位好友,也简单地聊了几句,但深感有些事情却再也不会回去了。 52 | 53 |
Yesterday is history, tomorrow is a mystery, today is God's gift, that's why we call it the present. - Joan Rivers
54 | 55 | *V.* 56 | 57 | *后记于 2019.01.03 午* 58 | -------------------------------------------------------------------------------- /Posts/Thought/190120/README.md: -------------------------------------------------------------------------------- 1 | # Thought - 20190120 2 | 3 | 在基础建设还不完善的时候,需要很多的搬砖劳工来献身建设;当建设到一定规模后,觉得以前的建筑不满足现在的需要,就可能推到重建。 4 | 5 | 所以越来越认识到,Programmer 其实基本上是金字塔最底层的,大部分任务是需要将 PRD 实现即可,而不需要也关心不到业务本身。只会去抱怨又改需求,而不知道为什么要改需求。然而技术只是手段,其门槛会越来越低,人会越来越多,泡沫也会变大。所以未来一定有新的工业革命来解放这些人的生产力了。不过,仔细想一想,解放生产力对谁来说是好事? 6 | 7 | --- 8 | 9 | 所以想想 996,周末加班的「现代互联网」企业和以前黑心的包工头有什么区别呢?他们不怕没有人来,所以即使你没有去,也有人去。所以这些最基本的东西也在一步步沦丧。 10 | 11 | --- 12 | 13 | 突然发现很多事情可以类比,我们在写代码的时候,在重复使用一个相同或相似输入输出的代码段时,久而久之,我们就会去把这段代码封装成函数,为了满足更多的需要,就会对其进行一定的抽象,之后我们就可以只调用这个函数,而不需要冗长又针对特定业务的代码段。其实生活、历史中的有些事情也是同理的。 14 | -------------------------------------------------------------------------------- /Posts/Tips/AirPlay_on_Pi/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/AirPlay_on_Pi/1.png -------------------------------------------------------------------------------- /Posts/Tips/AirPlay_on_Pi/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/AirPlay_on_Pi/2.jpg -------------------------------------------------------------------------------- /Posts/Tips/AirPlay_on_Pi/README.md: -------------------------------------------------------------------------------- 1 | # Tips - 将树莓派作为 AirPlay 音频服务器 2 | 3 | | Raspberry Pi | Platform | juhovh/shairplay | 4 | |:-----:|:-----:|:-----:| 5 | | 3 B | Raspbian 4.14 | 765148f98f343b3b9911cc05504ac276cfc44c26 | 6 | 7 | ## Info 8 | 9 | 树莓派是个很容易吃灰的设备,配置太低,又弃之可惜。何不作为 AirPlay 来解放你的有线音箱呢? 10 | 11 | ## Solution 12 | 13 | > SSH 或直接在树莓派的终端中运行以下命令,关于 SSH、VNC、替换源等操作请自行搜索。 14 | 15 | ### Basic setup 16 | 17 | - 安装依赖 18 | 19 | ``` 20 | sudo apt-get install autoconf automake libtool 21 | sudo apt-get install libltdl-dev libao-dev libavahi-compat-libdnssd-dev 22 | sudo apt-get install avahi-daemon 23 | ``` 24 | 25 | - 编译安装 26 | 27 | ``` 28 | cd ~/Desktop 29 | mkdir AirPlay 30 | cd AirPlay 31 | 32 | git clone https://github.com/juhovh/shairplay.git 33 | cd shairplay 34 | 35 | ./autogen.sh 36 | ./configure 37 | make 38 | sudo make install 39 | ``` 40 | 41 | - 启动 42 | - `-a` 后的参数 为 AirPlay 的名称,可自定义,eg. `HomePod` 43 | - 注意该命令必须在下载源码的路径中运行 44 | 45 | ``` 46 | shairplay -a HomePod 47 | ``` 48 | 49 | - 至此,即可在同一局域网环境下的 Apple 设备中发现该 AirPlay 音箱,但如果终端窗口关闭,则会终止运行 50 | 51 | ![shairplay -a HomePod](1.png) 52 | 53 | ### 后台运行 54 | 55 | - 安装 Supervisor(可参考前文) 56 | - 配置 57 | - 注意第一个 `command` 需要切换到 ShairPlay 源代码的路径 58 | 59 | ```ini 60 | ; shareplay.ini 61 | [program:shairplay] 62 | command=cd /home/pi/Desktop/ShairPlay/shairplay 63 | command=shairplay -a HomePod 64 | autostart=true 65 | autorestart=true 66 | startretries=5 67 | user=pi 68 | 69 | [supervisord] 70 | ``` 71 | 72 | - 在 supervisor.conf 中包含上述配置文件即可 73 | 74 | ```conf 75 | [include] 76 | files=shairplay.ini 77 | 78 | [supervisorctl] 79 | ``` 80 | 81 | - 运行 Supervisor 82 | 83 | ``` 84 | # superviord -c ${SUPERVISOR_CONFIG_PATH} 85 | sudo supervisord -c /etc/supervisor/conf.d/supervisord.conf 86 | ``` 87 | 88 | - Enjoy it! 89 | 90 | ![AirPlay on iPhone](2.jpg) 91 | 92 | ## Reference 93 | 94 | - [juhovh/shairplay](https://github.com/juhovh/shairplay) 95 | - [Supervisor 的安装与基本使用](https://github.com/kingcos/Perspective/issues/9) 96 | 97 | ## Extension 98 | 99 | - 开机自启动 & 噪音消除 100 | - [跟着上手树莓派(三)—— 让你的有线音箱从此无拘无束](https://sspai.com/post/39839) 101 | - [moOde audio player](http://www.moodeaudio.org) 102 | -------------------------------------------------------------------------------- /Posts/Tips/JDK_Multiple_Versions/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/JDK_Multiple_Versions/1.png -------------------------------------------------------------------------------- /Posts/Tips/JDK_Multiple_Versions/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/JDK_Multiple_Versions/2.png -------------------------------------------------------------------------------- /Posts/Tips/JDK_Multiple_Versions/README.md: -------------------------------------------------------------------------------- 1 | # Tips - 简单管理多版本 JDK 2 | 3 | | Platform | Notes | 4 | |:-----:|:-----:| 5 | | macOS 10.13.4 | JDK 8 & 9 | 6 | 7 | ## Solution 8 | 9 | - 安装 JDK 8 & 9(其他版本同理) 10 | - `vim ~/.zsh_rc`(这里使用的是 BashShell,其他 Shell 自行替换) 11 | - 文末追加: 12 | 13 | ```shell 14 | # Java 15 | export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8) 16 | export JAVA_9_HOME=$(/usr/libexec/java_home -v9) 17 | 18 | # Default for Java 8 19 | export JAVA_HOME=$JAVA_8_HOME 20 | 21 | alias java9='export JAVA_HOME=$JAVA_9_HOME' 22 | alias java8='export JAVA_HOME=$JAVA_8_HOME' 23 | ``` 24 | 25 | ![.zsh_rc](1.png) 26 | 27 | - 切换版本:`java8` / `java9` 28 | - 检查版本:`java -version` 29 | 30 | ![Terminal](2.png) 31 | 32 | ## Extension 33 | 34 | - [jenv](https://github.com/gcuisinier/jenv) 35 | -------------------------------------------------------------------------------- /Posts/Tips/Jenkins_by_Homebrew/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Jenkins_by_Homebrew/1.png -------------------------------------------------------------------------------- /Posts/Tips/Jenkins_by_Homebrew/README.md: -------------------------------------------------------------------------------- 1 | # Tips - 使用 Homebrew 安装 Jenkins 2 | 3 | | Platform | Notes | 4 | |:-----:|:-----:| 5 | | macOS 10.13.4 | Jenkins 2.114 & Java 8 | 6 | 7 | ## Solution 8 | 9 | - 安装 Homebrew 10 | 11 | ```shell 12 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 13 | ``` 14 | 15 | - 安装 Jenkins 16 | 17 | ```shell 18 | brew install jenkins 19 | ``` 20 | 21 | - 运行 Jenkins 22 | 23 | ```shell 24 | # 当前窗口启动(关闭窗口则关闭 Jenkins) 25 | # $JENKINS_VERSION_CODE 为版本号,$PORT 为 Jenkins Web 页面端口号 26 | # java -jar /usr/local/Cellar/jenkins/$JENKINS_VERSION_CODE/libexec/jenkins.war --httpPort=$PORT 27 | java -jar /usr/local/Cellar/jenkins/$JENKINS_VERSION_CODE/libexec/jenkins.war --httpPort=8080 28 | 29 | # 后台启动(关闭窗口无影响) 30 | # $OUTPUT_FILENAME 为终端输出内容存放的文件名 31 | # nohup java -jar /usr/local/Cellar/jenkins/$JENKINS_VERSION_CODE/libexec/jenkins.war >$OUTPUT_FILENAME & 32 | nohup java -jar /usr/local/Cellar/jenkins/2.114/libexec/jenkins.war >temp.txt & 33 | ``` 34 | 35 | ## Tips 36 | 37 | - 若出现下图问题,可能是 Jenkins 尚未很好支持 Java 9,请安装 Java 8 后再重装以兼容: 38 | 39 | ![Jenkins Oops!](1.png) 40 | 41 | ## Extension 42 | 43 | - [简单管理多版本 JDK](https://github.com/kingcos/Perspective/issues/7) 44 | -------------------------------------------------------------------------------- /Posts/Tips/Livestreaming_on_macOS/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Livestreaming_on_macOS/1.png -------------------------------------------------------------------------------- /Posts/Tips/Livestreaming_on_macOS/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Livestreaming_on_macOS/2.png -------------------------------------------------------------------------------- /Posts/Tips/Livestreaming_on_macOS/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Livestreaming_on_macOS/3.png -------------------------------------------------------------------------------- /Posts/Tips/Livestreaming_on_macOS/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Livestreaming_on_macOS/4.png -------------------------------------------------------------------------------- /Posts/Tips/Livestreaming_on_macOS/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Livestreaming_on_macOS/5.png -------------------------------------------------------------------------------- /Posts/Tips/Livestreaming_on_macOS/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Livestreaming_on_macOS/6.png -------------------------------------------------------------------------------- /Posts/Tips/Livestreaming_on_macOS/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Livestreaming_on_macOS/7.png -------------------------------------------------------------------------------- /Posts/Tips/Livestreaming_on_macOS/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Livestreaming_on_macOS/8.png -------------------------------------------------------------------------------- /Posts/Tips/Livestreaming_on_macOS/README.md: -------------------------------------------------------------------------------- 1 | # Tips - 在 macOS 上进行直播推流 2 | 3 | | Date | Platform | Software | 4 | |:-----:|:-----:|:-----:| 5 | | 2018.07.22 | macOS 10.14 beta 4 | OBS Studio, Soundflower 6 | | 2019.03.30 | macOS 10.14.4 | - | 7 | 8 | > 由于更换了电脑,上次好不容易折腾的配置也都无从参考,这次尽力把整个配置过程,以及音频输入输出的部分完善。直播推流使用了 OBS Studio,直播平台为 Bilibili。 9 | > 10 | > 欢迎来围观我的直播间:[https://live.bilibili.com/7900407](https://live.bilibili.com/7900407)。 11 | 12 | ## Solution 13 | 14 | ### Basic setup 15 | 16 | ![OBS Studio](1.png) 17 | 18 | - 使用「Homebrew」安装 OBS 19 | 20 | ``` 21 | brew cask install obs 22 | ``` 23 | 24 | ![Install with brew cask](2.png) 25 | 26 | - 安装期间可以在 Bilibili 申请开通直播,并获取需要的 RTMP 地址以及直播码 27 | 28 | ![Bilibili 开播设置](3.png) 29 | 30 | - 打开「OBS」-「Preference」-「流」 31 | 32 | ![流](4.png) 33 | 34 | - 在「URL」和「流名称」分别填写 Bilibili 提供的 RTMP 地址以及直播码 35 | - 回到主界面为默认的场景添加来源,常用的是「显示捕获」(即完全把自己能看到推流出去)以及「窗口捕获」(即只把选中的窗口推流出去) 36 | - 点击「开始推流」即可开始直播 37 | 38 | ![OBS](5.png) 39 | 40 | ### Audio 41 | 42 | - 使用「Homebrew」安装 Soundflower 43 | 44 | ``` 45 | brew cask install soundflower 46 | ``` 47 | 48 | > ⚠️ 注意: 49 | > 50 | > 在安装过程中,可能出现需要授权而导致安装错误,此时需要手动允许并重新安装即可。 51 | 52 | #### 将 Mac 播放的音频外放 & 输出 OBS 53 | 54 | ![Audio MIDI Setup.app](6.png) 55 | 56 | - 打开系统自带的「Audio MIDI Setup.app」 57 | - 选择左下角的「+」-「Create Multi-Output Device」 58 | - 勾选「Soundflower (2ch)」和「MacBook Pro Speakers」 59 | 60 | ![Sound](7.png) 61 | 62 | - 打开系统设置「Preference」-「Sound」-「Output」 63 | - 切换为「Multi-Output Device」 64 | 65 | > ⚠️ 注意: 66 | > 67 | > 此时无法再调节音量大小,只能在各软件内部设置。 68 | 69 | ![OBS](8.png) 70 | 71 | - 在 OBS 的「Preference」-「音频」中,将「桌面音频设备」和「麦克风/辅助音频设备」设置为「Soundflower (2ch)」,确定即可 72 | 73 | #### 将 Mac 麦克风采集输出 OBS 74 | 75 | - Waiting for update. 76 | 77 | ## Reference 78 | 79 | - [OBS Studio](https://obsproject.com) 80 | - [Soundflower](https://soundflower.en.softonic.com/mac) 81 | - [如何使用 OBS 軟體在 Mac 電腦做桌面直播?- LIVEhouse.in](https://event.livehouse.in/zh-TW/tutorial/obs-mac.html) 82 | - [Mac 上利用 OBS 在 B 站直播 iPhone 上的王者荣耀 - 秋风木叶](http://blog.ykqmain.com/obs/) -------------------------------------------------------------------------------- /Posts/Tips/MySQL_by_Homebrew/README.md: -------------------------------------------------------------------------------- 1 | # Tips - 使用 Homebrew 安装 MySQL 2 | 3 | | Platform | Notes | 4 | |:-----:|:-----:| 5 | | macOS 10.13.4 | MySQL 5.7.21 | 6 | 7 | ## Solution 8 | 9 | - 安装 Homebrew 10 | 11 | ```shell 12 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 13 | ``` 14 | 15 | - 安装 MySQL(注意观察可能有错误信息,比如 `brew link` 失败,可能要先在相应文件夹下开启「写」权限后再手动尝试) 16 | 17 | ```shell 18 | brew install mysql 19 | ``` 20 | 21 | - 开启 MySQL 服务 22 | 23 | ```shell 24 | # 现在启动,并加入自启动 25 | brew services start mysql 26 | 27 | # 后台启动 28 | mysql.server start 29 | ``` 30 | 31 | - 连接 MySQL(默认端口为 3306) 32 | 33 | ```shell 34 | mysql -uroot 35 | ``` 36 | 37 | - 创建用户并授权 38 | 39 | ```sql 40 | -- CREATE USER 'USERNAME'@'HOST_NAME' IDENTIFIED BY 'PASSWORD'; 41 | CREATE USER 'temp_user'@'localhost' IDENTIFIED BY '1234'; 42 | 43 | -- GRANT PRIVILEGE ON DATABASE_NAME.TABLE_NAME TO 'USERNAME'@'HOST_NAME' 44 | GRANT ALL ON *.* TO 'temp_user'@'localhost'; 45 | ``` 46 | 47 | - 关闭 MySQL 服务 48 | 49 | ```shell 50 | # 对应上述开启方法 51 | brew services stop mysql 52 | 53 | mysql.server stop 54 | ``` 55 | -------------------------------------------------------------------------------- /Posts/Tips/Obj-C_to_Cpp/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Obj-C_to_Cpp/1.png -------------------------------------------------------------------------------- /Posts/Tips/Obj-C_to_Cpp/README.md: -------------------------------------------------------------------------------- 1 | # Tips - 将 Obj-C 代码翻译为 C++ 代码 2 | 3 | | Platform | Notes | 4 | |:-----:|:-----:| 5 | | macOS 10.14.2 | clang | 6 | 7 | ## Solution 8 | 9 | ``` 10 | ➜ ~ clang --version 11 | Apple LLVM version 10.0.0 (clang-1000.11.45.5) 12 | Target: x86_64-apple-darwin18.2.0 13 | Thread model: posix 14 | InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin 15 | ``` 16 | 17 | Xcode 中,C/C++/Obj-C/C++ 的编译器是 clang。其加上 `-rewrite-objc` 参数可以将 Obj-C 代码翻译为 C++ 代码,即 `clang -rewrite-objc main.m -o main.cpp`。也可以结合 `xcrun` 设置编译所基于的 SDK,以及通过 `-arch` 指定编译架构参数,通过 `-framework` 指定需要依赖的框架,即 `xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp -framework UIKit`。 18 | 19 | ![clang --help | grep -rewrite-objc](1.png) 20 | 21 | 虽然 clang 可以将 Obj-C 代码翻译为 C++,但其实大部分代码都属于 C 语言,比如 Obj-C 的类,其本质是 C 语言中的结构体。而翻译存在的目的是因为 Windows 上的 Visual Studio 中并没有 Obj-C 的编译器,所以 clang 将 Obj-C 转为 C/C++,便于其他 C/C++ 编译器进行编译。在使用 Xcode 构建 Obj-C 项目时并不会将 Obj-C 进行翻译,clang 可以直接编译纯 Obj-C 代码。 22 | 23 | ## Reference 24 | 25 | - [StackOverflow - -rewrite-objc and Objective-C in clang](https://stackoverflow.com/questions/44561285/rewrite-objc-and-objective-c-in-clang) 26 | - [StackOverflow - What's the relationship between Objective-C source code and after clang -rewrite-objc C++ code?](https://stackoverflow.com/questions/55198496/whats-the-relationship-between-objective-c-source-code-and-after-clang-rewrite) -------------------------------------------------------------------------------- /Posts/Tips/Override_and_Overload_in_Obj-C/README.md: -------------------------------------------------------------------------------- 1 | # Tips - Obj-C 中的重载与重写 2 | 3 | | Platform | 4 | |:-----:| 5 | | macOS 10.14.2 | 6 | 7 | ## 重载 8 | 9 | > In some programming languages, function overloading or method overloading is the ability to create multiple functions of the same name with different implementations. Calls to an overloaded function will run a specific implementation of that function appropriate to the context of the call, allowing one function call to perform different tasks depending on context. 10 | > 11 | > Function overloading - Wikipedia 12 | > 13 | > 译: 14 | > 15 | > 在某些编程语言中,函数重载或方法重载是指一种可以创建多个同名函数但拥有不同实现的能力。调用重载函数将执行符合上下文的函数调用,即允许一个函数调用根据上下文执行不同的任务。 16 | > 17 | > 函数重载 - 维基百科 18 | 19 | 如维基百科所讲,简言之,重载(Overload)指在同一个类中,存在相同函数名但不同参数个数或不同参数类型或不同返回值的函数。但由于 Obj-C 是消息结构的语言,其意义上的方法调用实质上是消息传递。 20 | 21 | ```objc 22 | @interface Computer : NSObject 23 | 24 | - (void)run; 25 | - (void)run:(NSString *)sth; 26 | 27 | @end 28 | 29 | @implementation Computer 30 | 31 | - (void)run { 32 | NSLog(@"run"); 33 | } 34 | - (void)run:(NSString *)sth { 35 | NSLog(@"run - %@", sth); 36 | } 37 | 38 | @end 39 | 40 | int main(int argc, const char * argv[]) { 41 | @autoreleasepool { 42 | Computer *cpt = [[Computer alloc] init]; 43 | [cpt run]; 44 | [cpt run:@"sth"]; 45 | } 46 | return 0; 47 | } 48 | ``` 49 | 50 | 我们定义一个继承自 `NSObject` 的 `Computer` 类,其拥有两个实例方法。尝试将上述代码翻译为 C++,`xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-64.cpp`。由于 Obj-C 是消息结构的语言,`objc_msgSend` 处便是其消息传递之处,我们可以发现原本的方法都被变成了字符串:`sel_registerName("alloc")`、`sel_registerName("init")`、`sel_registerName("run")` 和 `sel_registerName("run:")`。实际上这些字符串就是 Obj-C 方法的方法名,方法名忽略了参数名以及返回值,实例方法与类方法的区别也只是不同的消息接收对象。所以严格意义上讲,Obj-C 是不支持方法重载的,因为它不允许同名函数的存在。但如果按不同参数个数也属于方法重载来说,Obj-C 仅支持参数个数不同的重载,每个参数都将在方法名后多生成一个 `:` 从而可以区分。 51 | 52 | ```cpp 53 | int main(int argc, const char * argv[]) { 54 | /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 55 | 56 | Computer *cpt = ((Computer *(*)(id, SEL))(void *)objc_msgSend)((id)((Computer *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Computer"), sel_registerName("alloc")), sel_registerName("init")); 57 | ((void (*)(id, SEL))(void *)objc_msgSend)((id)cpt, sel_registerName("run")); 58 | ((void (*)(id, SEL, NSString *))(void *)objc_msgSend)((id)cpt, sel_registerName("run:"), (NSString *)&__NSConstantStringImpl__var_folders_qt_ctbfp1yd2gn7bv6y6v6qgvgm0000gn_T_main_ea7dac_mi_0); 59 | } 60 | return 0; 61 | } 62 | ``` 63 | 64 | ## 重写 65 | 66 | > Method overriding, in object-oriented programming, is a language feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes. The implementation in the subclass overrides (replaces) the implementation in the superclass by providing a method that has same name, same parameters or signature, and same return type as the method in the parent class. The version of a method that is executed will be determined by the object that is used to invoke it. If an object of a parent class is used to invoke the method, then the version in the parent class will be executed, but if an object of the subclass is used to invoke the method, then the version in the child class will be executed. Some languages allow a programmer to prevent a method from being overridden. 67 | > 68 | > Method overriding - Wikipedia 69 | > 70 | > 译: 71 | > 72 | > 在面向对象编程中,方法重写是一种语言特性,它允许子类提供其父类或超类已经提供的特定方法实现。子类中的实现通过提供与父类中的方法相同的名称、相同的参数或签名以及相同的返回类型的方法来覆盖(替换)超类中的实现。执行方法的版本将由调用对象确定。如果父类对象调用该方法,则将执行父类中的版本,但如果使用子类对象调用该方法,则将执行子类中的版本。某些语言允许程序员阻止方法被覆盖。 73 | > 74 | > 方法重写 - 维基百科 75 | 76 | ```objc 77 | @interface Mac : Computer 78 | @end 79 | 80 | @implementation Mac 81 | 82 | - (void)run:(NSString *)sth { 83 | NSLog(@"Mac - run - %@", sth); 84 | } 85 | 86 | @end 87 | ``` 88 | 89 | 完全不同于重载,重写(Override)是指在子类中重写父类的方法,且方法名、参数类型、参数个数、返回值类型等必须一致。Obj-C 是完全支持方法重写的: 90 | 91 | ```objc 92 | Computer *cpt = [[Computer alloc] init]; 93 | [cpt run:@"cpt_run"]; 94 | Computer *mac = [[Mac alloc] init]; 95 | [mac run:@"mac_run"]; 96 | 97 | // OUTPUT: 98 | // run - cpt_run 99 | // Mac - run - mac_run 100 | ``` 101 | 102 | ## Reference 103 | 104 | - [Function overloading - Wikipedia](https://en.wikipedia.org/wiki/Function_overloading) 105 | - [Tips - 将 Obj-C 代码翻译为 C++ 代码](https://github.com/kingcos/Perspective/issues/72) 106 | - [Method overriding - Wikipedia](https://en.wikipedia.org/wiki/Method_overriding) -------------------------------------------------------------------------------- /Posts/Tips/Swift_GYB/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Tips/Swift_GYB/1.png -------------------------------------------------------------------------------- /Posts/Tips/Swift_GYB/README.md: -------------------------------------------------------------------------------- 1 | # Tips - Swift 源代码中的 GYB 2 | 3 | | Date | Notes | 4 | |:-----:|:-----:| 5 | | 2018-12-03 | 首次提交 | 6 | 7 | ## Preface 8 | 9 | 翻看过 Swift 在 GitHub 开源仓库的同学一定会见过「.swift.gyb」结尾的文件。其中的内容不像是纯 Swift 语法的代码,但又似乎遵循了某些格式,那么 GYB 是什么呢? 10 | 11 | ![Codable.swift.gyb](1.png) 12 | 13 | ## What 14 | 15 | GYB,全称 Generate Your Boilerplate。译成中文是「模版生成」,重点就在于「Boilerplate」。举个例子,在编写一门编程语言时,整型可能根据占据的不同大小内存以及有无符号而非为 Int,Int8,Int16,Int32,Int64,UInt,UInt8,UInt16,UInt32,UInt64 多种。而对于这些类型的一些通用操作、方法调用,其实都是重复性的。拷贝、粘贴虽然似乎也能解决问题,但后续如果有一些实现上的变更,则不利于快速同步变更。所以 GYB 文件就是 Swift 代码的模版,使用模版文件则即可很方便快捷地创建重复性的代码逻辑。 16 | 17 | ## Reference 18 | 19 | - [apple/swift](https://github.com/apple/swift) 20 | 21 | ## Extension 22 | 23 | - [Swift GYB - Mattt (EN)](https://nshipster.com/swift-gyb/) 24 | - [Swift GYB - Mattt (CN)](https://nshipster.cn/swift-gyb/) 25 | -------------------------------------------------------------------------------- /Posts/Tips/Xcode_10_beta/README.md: -------------------------------------------------------------------------------- 1 | # Tips - Xcode 10 beta 趟坑 2 | 3 | | Xcode | macOS | 4 | |:-----:|:-----:| 5 | | 10 beta 2 | 10.14 beta 2 | 6 | 7 | ## $(TeamIdentifierPrefix) 8 | 9 | - Xcode 10 已知 Bug,无法自动替换。 10 | 11 | ### Workaround 12 | 13 | - 可以手动将 entitlements 文件的 `Pass Type ID` 值设置为 mobileversion 文件中`com.apple.developer.pass-type-identifiers` 对应值。 14 | 15 | ## libstdc++ 16 | 17 | - Xcode 10 取消了内置支持的 libstdc++ 库,需等待某些第三方 SDK 修复。 18 | 19 | ### Workaround 20 | 21 | - 手动将 Xcode 9(`/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib`)中的库 `libstdc++.6.tbd` & `libstdc++.6.0.9.tbd` 复制到 Xcode 10(`/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib`)。 22 | 23 | ## SWIFT_UNAVALIABLE 24 | 25 | - 在 Obj-C 中调用 Swift 子类的 Obj-C 父类的构造器,提示 Unavaliable,由 Xcode 生成的 `*-Swift.h` 会将方法标记为 `SWIFT_UNAVALIABLE`。这是因为子类没有继承的构造器,将无法被调用。 26 | - Reference: 27 | - [https://github.com/apple/swift/commit/0473e99988fcab251adc251cf8f44673bdabad9d](https://github.com/apple/swift/commit/0473e99988fcab251adc251cf8f44673bdabad9d) 28 | 29 | ### Workaround 30 | 31 | - 将构造器在 Swift 子类中重写(内部直接调用 `super` 即可),并用 `public` 修饰。 32 | 33 | ## ld: symbol(s) not found for architecture arm64 34 | 35 | - 可以尝试仍使用传统构建系统(Legacy build system)构建,在 File-Workspace Settings 中设置; 36 | - 但在我们的项目中,使用新旧构建系统均会出错,具体原因和解决方法未知。 37 | -------------------------------------------------------------------------------- /Posts/Tips/iOS_Dev_Issue_List/README.md: -------------------------------------------------------------------------------- 1 | # Tips - iOS 开发问题解决集锦 2 | 3 | ## Unable to boot device in current state: Creating 4 | 5 | - Xcode: 9.4.1 6 | - macOS: 10.13 7 | - 在使用模拟器或者 `xcodebuild test` 时可能会出现此问题。 8 | 9 | ### Solution 10 | 11 | - 使用 `xcrun simctl list` 命令列出所有模拟器机型,用 `xcrun simctl erase UDID` 还原相应的设备,重试即可。 12 | - 下面是一个 Python 3 脚本,可以使用 `python erase_simulators.py -d 'DEVICE_TYPE'` 来直接还原相应设备类型的所有设备。 13 | 14 | ```python 15 | # -*- coding: utf-8 -*- 16 | 17 | import argparse 18 | import subprocess 19 | import re 20 | 21 | def erase_device(device): 22 | status, output = subprocess.getstatusoutput('xcrun simctl list | grep \'' + device + ' (\'') 23 | if status == 0: 24 | outputs = output.split('\n') 25 | for output in outputs: 26 | simulator_udids = re.findall('[A-Z0-9-]{36}', output) 27 | if simulator_udids != []: 28 | for udid in simulator_udids: 29 | subprocess.getstatusoutput('xcrun simctl erase' + udid) 30 | print('Already erased ' + device + ' - UDID: ' + udid) 31 | 32 | if __name__ == '__main__': 33 | iphone_64_devices = ['iPhone 5s', 'iPhone 6', 'iPhone 6 Plus', 'iPhone 6s', 'iPhone 6s Plus', 'iPhone 7', 'iPhone 7 Plus', 'iPhone 8', 'iPhone 8 Plus', 'iPhone X'] 34 | parser = argparse.ArgumentParser() 35 | parser.add_argument('-d', '--device', help='Specify the simulator device, eg. iPhone X', choices=iphone_64_devices) 36 | args = parser.parse_args() 37 | if args.device is not None: 38 | erase_device(args.device) 39 | else: 40 | print('Please specify the device option!') 41 | ``` 42 | 43 | ### The operation couldn’t be completed. (DVTCoreSimulatorAdditionsErrorDomain error 0.) 44 | 45 | - Xcode: 10 46 | - macOS: 10.14 47 | - 在清空了 `~/Library/Developer/CoreSimulator/Devices` 后 `xcodebuild test` 时出现此问题。 48 | 49 | ### Solution 50 | 51 | ```sh 52 | xcrun simctl erase all 53 | ``` 54 | 55 | ## Cannot find "$(SRCROOT)/*/Info.plist" 56 | 57 | - Fastlane `increment_version_number` 58 | - `agvtool new-marketing-version x.x.x` 59 | - 某些 Target 无法使用命令批量更新版本号时出现此问题。 60 | 61 | ### Solution 62 | 63 | - 在项目的 Build Settings 中搜索 `$(SRCROOT)`,删除包含该内容条目中的 `$(SRCROOT)` 变量(通常是 `INFOPLIST_FILE` 字段)。 64 | 65 | ## Failed to verify bitcode in * 66 | 67 | - 当主 Target 未开启 Bitcode 时,Archive 后,通常有「Rebuild from bitcode」选项,勾选时可能会出现此问题; 68 | - 抑或使用 Fastlane「build_ios_app」打包,出现该问题。 69 | 70 | ### Solution 71 | 72 | - 手动打包不勾选「Rebuild from bitcode」选项即可; 73 | - Fastlane 需要在关闭 Bitcode,具体如下: 74 | 75 | ```ruby 76 | build_ios_app(export_options: { compileBitcode: false }) 77 | ``` 78 | 79 | ## Missing password for user xxx@yyy.com, and running in non-interactive shell 80 | 81 | - Fastlane 上传 App Store 时会出现该问题。 82 | 83 | ### Solution 84 | 85 | - 根据 [https://github.com/fastlane/fastlane/tree/master/credentials_manager](https://github.com/fastlane/fastlane/tree/master/credentials_manager) 添加打包上传 App Store 的 Apple ID 资格,如需更改密码,可先移除再添加即可(需搭配 unlock_keychain 使用)。 86 | 87 | ## No value found for 'username' 88 | 89 | - Fastlane 上传 App Store 时会出现该问题。 90 | 91 | ### Solution 92 | 93 | - `No value found for 'username'` 是 Pilot([upload_to_testflight](https://docs.fastlane.tools/actions/upload_to_testflight/))的报错信息; 94 | - 可在 AppFile 配置上传 App Store 的 Apple ID,或在 upload_to_testflight 添加 username 参数,并按照上条 Tips 添加账号密码至 Key Chain。 95 | 96 | ## Please see Simulator Help for information on adjusting system settings to allow more simulated devices to boot at once. 97 | 98 | - 在使用模拟器作为 destination 时出现此错误。 99 | 100 | ### Solution 101 | 102 | - [官方文档](https://help.apple.com/simulator/mac/9.0/index.html#/dev8a5f2aa4e)。 103 | 104 | ```shell 105 | sudo launchctl limit maxproc 2000 2500 106 | ``` 107 | 108 | ## 在 iPhone X 及以上全面屏机型 UIWebView 的内容未填充整个视图 109 | 110 | - 视图层级关系:UIWebView > UIWebScrollView > UIWebBrowserView 111 | - 由于 iPhone X 带来的全面屏,系统会自动对其中的 UIWebBrowserView 进行调整,导致即使设置 UIWebView 整体的约束,显示的内容区域也时有问题。 112 | 113 | ### Solution 114 | 115 | - 将其中的 UIScrollView 的自动调整行为关闭即可。 116 | 117 | ```swift 118 | if #available(iOS 11.0, *) { 119 | webView.scrollView.contentInsetAdjustmentBehavior = .never 120 | } 121 | ``` 122 | -------------------------------------------------------------------------------- /Posts/Tips/usbmuxd/README.md: -------------------------------------------------------------------------------- 1 | # Tips - 使用 usbmuxd 连接 iPhone 2 | 3 | | macOS | iOS | libimobiledevice/usbmuxd | 4 | |:-----:|:-----:|:-----:| 5 | | 10.13.6 | 9.0.1 (Jailbroken) | v1.0.8 | 6 | 7 | ## What 8 | 9 | usbmuxd 全称「USB Multiplexing Daemon」,即 USB 多路传输驻留程序。当 Mac/PC 与 iPhone 之间使用 USB 数据线连接时,iTunes 与 iPhone 间的通信交流便是通过 usbmuxd 服务。usbmuxd 通过给定的端口号和 localhost 建立 TCP 连接。 10 | 11 | 在 Mac 端,是由「/System/Library/PrivateFrameworks/MobileDevice.framework/Resources/usbmuxd」处理,并通过 launchd 启动。其将会在「/var/run/usbmuxd」创建一个 UNIX Domain Socket(UNIX 域套接字),usbmuxd 将监听 USB 接口的 iPhone 连接。当 iPhone 在正常模式下连接,其将会连接到该 iPhone,并将开始转发通过「/var/run/usbmuxd」接收到的请求。 12 | 13 | ## Solution 14 | 15 | > 通过 usbmuxd 用 USB 代替 Wi-Fi 转发 SSH 请求。 16 | 17 | - 这里注意选择 1.0.8 版本,更高版本使用了 C/C++ 等方式实现,和以下操作将有较大差异。 18 | - 开启服务: 19 | 20 | ```shell 21 | cd usbmuxd-1.0.8/python-client 22 | 23 | # python tcprelay.py -t 22:PORT_NUMBER 24 | python tcprelay.py -t 22:9090 25 | ``` 26 | 27 | - 之后便可以 SSH 到本机的 9090 端口即可: 28 | 29 | ```shell 30 | ssh root@localhost -p 9090 31 | ``` 32 | 33 | ## Reference 34 | 35 | - [Usbmux](https://www.theiphonewiki.com/wiki/Usbmux) 36 | - [libimobiledevice/usbmuxd](https://github.com/libimobiledevice/usbmuxd) -------------------------------------------------------------------------------- /Posts/Translation/About_the_App_Launch_Sequence/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Translation/About_the_App_Launch_Sequence/1.png -------------------------------------------------------------------------------- /Posts/Translation/About_the_App_Launch_Sequence/README.md: -------------------------------------------------------------------------------- 1 | # Translation - [译]关于 App 启动顺序 2 | 3 | 作者 | 原文链接 4 | --- | --- 5 | Apple Inc. | [About the App Launch Sequence](https://developer.apple.com/documentation/uikit/core_app/managing_your_app_s_life_cycle/responding_to_the_launch_of_your_app/about_the_app_launch_sequence) 6 | 7 | 学习在启动时的代码执行顺序。 8 | 9 | - **框架** 10 | - UIKit 11 | 12 | --- 13 | 14 | ## 概览 15 | 16 | 一个 App 的启动需要经过许多复杂的步骤,其中大部分由 UIKit 自动处理。在启动过程中,UIKit 会调用 App 代理中的方法,因此我们可以执行自定义的任务。图中的步骤展示了从 App 启动的时间开始直到被认为初始化完成的过程。 17 | 18 | ![图例 1 App 启动和初始化序列](1.png) 19 | 20 | 1. 由用户显式或系统隐式启动 App。 21 | 2. Xcode 提供的 `main` 函数调用 UIKit 的 [`UIApplicationMain(_:_:_:_:)`](https://developer.apple.com/documentation/uikit/1622933-uiapplicationmain) 函数。 22 | 3. [`UIApplicationMain(_:_:_:_:)`](https://developer.apple.com/documentation/uikit/1622933-uiapplicationmain) 函数创建 [`UIApplication`](https://developer.apple.com/documentation/uikit/uiapplication) 对象和 App 代理。 23 | 4. UIKit 从主 storyboard 或 nib 文件加载 App 的默认界面。 24 | 5. UIKit 调用 App 代理的 [`application(_:willFinishLaunchingWithOptions:)`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623032-application) 方法。 25 | 6. UIKit 执行状态恢复(state restoration),即调用 App 代理和视图控制器中的额外的方法。 26 | 7. UIKit 调用 App 代理的 [`application(_:didFinishLaunchingWithOptions:)`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622921-application) 方法。 27 | 28 | 当初始化完成,系统将 App 转到激活(前台)状态或后台状态。当 App 转到激活状态,其窗口出现在屏幕上,并开始响应用户交互。当 App 转到后台状态,其窗口保持隐藏,并在被暂停前运行极短的时间。 29 | 30 | 不管 App 启动到前台还是后台,大部分启动时间初始化的代码应当是相同的。举个例子,我们应当依旧初始化 App 的数据结构,并设置 App 用户界面。但是,如果有只在前台或后台运行的自定义的任务,检查 [`UIApplication`](https://developer.apple.com/documentation/uikit/uiapplication) 对象的 [`applicationState`](https://developer.apple.com/documentation/uikit/uiapplication/1623003-applicationstate) 属性即可。当 App 运行到前台时,UIKit 设置该属性为 [`UIApplication.State.inactive`](https://developer.apple.com/documentation/uikit/uiapplication/state/inactive),当 App 运行到后台时,UIKit 设置该属性为 [`UIApplication.State.background`](https://developer.apple.com/documentation/uikit/uiapplication/state/background)。 31 | 32 | ## 参阅 33 | 34 | ### 启动时间 35 | 36 | - [为 App 执行一次性设置(Performing One-Time Setup for Your App)](https://developer.apple.com/documentation/uikit/core_app/managing_your_app_s_life_cycle/responding_to_the_launch_of_your_app/performing_one-time_setup_for_your_app) 37 | - 确保 App 环境被正确配置。 38 | 39 | --- 40 | 41 | > 以下内容为译者添加: 42 | 43 | ## 参考 44 | 45 | - [[译]为 App 执行一次性设置](https://github.com/kingcos/Perspective/issues/59) 46 | -------------------------------------------------------------------------------- /Posts/Translation/Designating_Nullability_in_Objective-C_APIs/README.md: -------------------------------------------------------------------------------- 1 | # Translation - [译]在 Objective-C API 中指定可空性 2 | 3 | 作者 | 原文链接 4 | --- | --- 5 | Apple Inc. | [Designating Nullability in Objective-C APIs](https://developer.apple.com/documentation/swift/objective-c_and_c_code_customization/designating_nullability_in_objective-c_apis) 6 | 7 | 使用可空性(Nullability)标志或标志一块区域,以控制将 Objective-C 声明导入 Swift 中的方式。 8 | 9 | - **框架:** 10 | - Swift 标准库 11 | 12 | --- 13 | 14 | ## 概览 15 | 16 | 在 Objective-C 中,常用可以为空的指针来和对象的引用打交道,这(个空)就是 Objective-C 中的 `nil`。在 Swift 中,所有值——包括对象实例——都被确保为非空(Non-null)。取而代之,表示一个可能丢失的值可以将其包裹在可选(Optional)类型中。当我们需要表示一个值的丢失,可以使用 `nil` 值。 17 | 18 | 我们可以在 Objective-C 的代码中标示声明,以指示一个实例是否可以有空(Null)或 `nil` 值。这些标志改变了 Swift 如何导入声明(的方式)。举个 Swift 如何导入未标示声明的例子,如下: 19 | 20 | ```objc 21 | @interface MyList : NSObject 22 | - (MyListItem *)itemWithName:(NSString *)name; 23 | - (NSString *)nameForItem:(MyListItem *)item; 24 | @property (copy) NSArray *allItems; 25 | @end 26 | ``` 27 | 28 | Swift 导入了每个对象实例的参数、返回值、以及作为隐式包裹可选的属性(译者注:隐式包裹即 `Type!`,表示该值被保证为非 nil,即可在后续使用时省略 `?` 解包,但当该值为 nil 却没有使用可选解包时,程序将发生崩溃,该点也在另外一篇文章内有提及,有需要的读者可以参考文末 Reference 部分)。 29 | 30 | ```swift 31 | class MyList: NSObject { 32 | func item(withName name: String!) -> MyListItem! 33 | func name(for item: MyListItem!) -> String! 34 | var allItems: [MyListItem]! 35 | } 36 | ``` 37 | 38 | ## 为单独的声明标记可空性 39 | 40 | 在 Objective-C 代码中使用可空性标志可以指定参数类型、属性类型、或者返回值类型是否为可空的。标示属性声明、参数类型、以及返回值类型这些简单对象或者 Block 指针,可以使用 `nullable`、`nonnull`、以及 `null_resettable` 属性标志。如果一个类型没有提供可空性信息,Swift 将不区分可选和非可选引用,并将该类型作为隐式可选解包导入。 41 | 42 | 下表描述了 Swift 如何导入带有不同可空性标志的类型: 43 | 44 | - 非空(Nonnullable)——无论是直接标示抑或包含在一个标示区域内,都作为非可选(类型)导入 45 | - 可空(Nullable)——作为可选(类型)导入 46 | - 不带有可空性标示或 `null_resettable` 标志——作为隐式解包可选(类型)导入 47 | 48 | 下面的代码展示了标示后的 `MyList` 类型。两个方法的返回值被标示为 `nullable`,因为如果列表不包含给定的列表项或名称,方法将返回 `nil`。所有其他对象实例均被标示为 `nonnull`。 49 | 50 | ```objc 51 | @interface MyList : NSObject 52 | - (nullable MyListItem *)itemWithName:(nonnull NSString *)name; 53 | - (nullable NSString *)nameForItem:(nonnull MyListItem *)item; 54 | @property (copy, nonnull) NSArray *allItems; 55 | @end 56 | ``` 57 | 58 | 通过这些标志,Swift 将不使用任何隐式包裹可选来导入 `MyList` 类型: 59 | 60 | ```swift 61 | class MyList: NSObject { 62 | func item(withName name: String) -> MyListItem? 63 | func name(for item: MyListItem) -> String? 64 | var allItems: [MyListItem] 65 | } 66 | ``` 67 | 68 | `nullable` 和 `nonnull` 标志是 `_Nullable` 和 `_Nonnull` 的简化版。当对指针类型使用 `const` 关键字时,我们可以在绝大多数上下文中使用它们。复杂的指针类型,比如 `id *` 必须明确标示所使用的标志。举个例子,一个指向可空对象引用的不可空的指针,声明为 `_Nullable id * _Nonnull`。 69 | 70 | ## 标示区域不可空 71 | 72 | >(译者注:原标题为 Annototate Regions as Nonnullable,但英文中并无 Annototate 一词,结合上下文此处应该是 Annotate 的笔误,特此注明。) 73 | 74 | 通过标示整个区域为可空性检查可以简化标示 Objective-C 代码的过程。标记 `NS_ASSUME_NONNULL_BEGIN` 和 `NS_ASSUME_NONNULL_END` 之间区域内的代码,只需要标示可空类型的声明。未标记声明的部分将被当作是非空的。 75 | 76 | 将 `MyList` 声明标记为可空性检查降低了所需要的标志数量。Swift 将以与上一节相同的方式导入该类型。 77 | 78 | ```objc 79 | NS_ASSUME_NONNULL_BEGIN 80 | 81 | @interface MyList : NSObject 82 | - (nullable MyListItem *)itemWithName:(NSString *)name; 83 | - (nullable NSString *)nameForItem:(MyListItem *)item; 84 | @property (copy) NSArray *allItems; 85 | @end 86 | 87 | NS_ASSUME_NONNULL_END 88 | ``` 89 | 90 | 注意,尽管在检查区域内,但`typedef` 的类型不会被假定为非空,因为它们内在并非是可空的。 91 | 92 | ## 参阅 93 | 94 | ### 定制 Objective-C API 95 | 96 | ### [为 Swift 重命名 Objective-C API](https://developer.apple.com/documentation/swift/objective-c_and_c_code_customization/renaming_objective-c_apis_for_swift) 97 | 98 | 使用 `NS_SWIFT_NAME` 宏为 Swift 定制 API 名称。 99 | 100 | ### [为 Swift 改进 Objective-C 声明](https://developer.apple.com/documentation/swift/objective-c_and_c_code_customization/improving_objective-c_api_declarations_for_swift) 101 | 102 | 使用 `NS_REFINED_FOR_SWIFT` 宏以改变 API 是如何导入 Swift 中的。 103 | 104 | ### [组合相关的 Objective-C 常量](https://developer.apple.com/documentation/swift/objective-c_and_c_code_customization/grouping_related_objective-c_constants) 105 | 106 | 在 Objective-C 类型中添加宏以在 Swift 中组合他们的值。 107 | 108 | ### [在 Objective-C 中标记 API 可用性](https://developer.apple.com/documentation/swift/objective-c_and_c_code_customization/marking_api_availability_in_objective-c) 109 | 110 | 使用宏以表示 Objective-C API 的可用性。 111 | 112 | ### [让 Objective-C API 在 Swift 中不可用](https://developer.apple.com/documentation/swift/objective-c_and_c_code_customization/making_objective-c_apis_unavailable_in_swift) 113 | 114 | 使用 `NS_SWIFT_UNAVAILABLE` 宏以在 Swift 中禁用 API。 115 | 116 | --- 117 | 118 | > 译者注: 119 | > 120 | > 1. API 即通用意义上的接口,不再翻译; 121 | > 122 | > 2. 由于 Null 和 Nil 含义类似,均为空,在本文中为表区分,将 Null 翻译为「空」,Nil 不作翻译,代码中不会进行任何翻译; 123 | > 124 | > 3. 由于英文语法规范,通常会有主语 You,我可能会在不改变核心意义的情况下,会忽略人称,在部分情况将其改为第一人称「我们」。 125 | 126 | ## Reference 127 | 128 | - [kingcos - Objective-C 与 Swift 桥接中的坑](https://github.com/kingcos/Perspective/issues/68) -------------------------------------------------------------------------------- /Posts/Translation/Performing_One-Time_Setup_for_Your_App/README.md: -------------------------------------------------------------------------------- 1 | # Translation - [译]为 App 执行一次性设置 2 | 3 | 作者 | 原文链接 4 | --- | --- 5 | Apple Inc. | [Performing One-Time Setup for Your App](https://developer.apple.com/documentation/uikit/core_app/managing_your_app_s_life_cycle/responding_to_the_launch_of_your_app/performing_one-time_setup_for_your_app) 6 | 7 | 确保 App 环境被正确配置。 8 | 9 | - **框架** 10 | - UIKit 11 | 12 | --- 13 | 14 | ## 概览 15 | 16 | 当用户第一次启动 App,我们可能希望通过一些一次性任务预备 App 环境。举个例子,可能想要: 17 | 18 | - 从服务器下载必要的数据。 19 | - 从 App 包(bundle)中拷贝文档模版或可修改的数据文件至一个可写入的目录。 20 | - 为用户配置默认偏好设置。 21 | - 设置用户账户或获取其他必要数据。 22 | 23 | 在 App 代理的 [`application(_:willFinishLaunchingWithOptions:)`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623032-application) 或 [`application(_:didFinishLaunchingWithOptions:)`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622921-application) 方法中执行任何一次性任务。当非必需用户输入时,绝不要因任务阻塞 App 的主线程。取而代之,使用调度队列(dispatch queue)异步开启任务,当 App 完成启动时,让其运行在后台。对于那些必需用户输入的任务,在 `application(_:didFinishLaunchingWithOptions:)` 方法中作出用户界面的改变。 24 | 25 | ### 在合适的位置安放文件 26 | 27 | App 拥有其自身包含的目录来保存文件,我们也应当总是将 App 特定的文件放在 `~/Library` 的子目录中。特别地,将以下文件保存在 `~/Library` 的子目录: 28 | 29 | - `~/Library/Application Support/` —— 保存想要备份用户的其他内容的 App 特定文件(可以根据需要创建自定义的子目录。)使用该目录保存数据文件,配置文件,文档模版,等等。 30 | - `~/Library/Caches/` —— 保存便于重复产生或下载的临时文件。 31 | 32 | 使用 [`FileManager `](https://developer.apple.com/documentation/foundation/filemanager) 的 [`urls(for:in:) `](https://developer.apple.com/documentation/foundation/filemanager/1407726-urls) 方法获得 App 容器的目录 URL。 33 | 34 | ```swift 35 | // 列表 1 获取 App 制定目录的位置 36 | let appSupportURL = FileManager.default.urls(for: 37 | .applicationSupportDirectory, in: .userDomainMask) 38 | 39 | let cachesURL = FileManager.default.urls(for: 40 | .cachesDirectory, in: .userDomainMask) 41 | ``` 42 | 43 | 在 App 的 `tmp/` 目录下存放任何的临时文件。临时文件可能包含压缩文件,一旦其内容被提取并装载到其他地方后我们就打算删除。使用 [`FileManager `](https://developer.apple.com/documentation/foundation/filemanager) 的 [`temporaryDirectory `](https://developer.apple.com/documentation/foundation/filemanager/1642996-temporarydirectory) 方法获取 App 临时目录的 URL。 44 | 45 | ## 参阅 46 | 47 | ### 启动时间 48 | 49 | - [关于 App 启动顺序(About the App Launch Sequence)](https://developer.apple.com/documentation/uikit/core_app/managing_your_app_s_life_cycle/responding_to_the_launch_of_your_app/about_the_app_launch_sequence) 50 | - 学习在启动时的代码执行顺序。 51 | 52 | --- 53 | 54 | > 以下内容为译者添加: 55 | 56 | ## 参考 57 | 58 | - [[译]关于 App 启动顺序](https://github.com/kingcos/Perspective/issues/58) -------------------------------------------------------------------------------- /Posts/Translation/URL_Loading_System/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Translation/URL_Loading_System/1.png -------------------------------------------------------------------------------- /Posts/Translation/URL_Loading_System/README.md: -------------------------------------------------------------------------------- 1 | # Translation - [译]URL 加载系统 2 | 3 | 作者 | 原文链接 4 | --- | --- 5 | Apple Inc. | [URL Loading System](https://developer.apple.com/documentation/foundation/url_loading_system) 6 | 7 | 使用标准互联网协议与 URL 交互,并和服务器通信。 8 | 9 | - **框架:** 10 | - Foundation 11 | 12 | --- 13 | 14 | ## 概览 15 | 16 | URL 加载系统通过标准协议比如 HTTPS 或自建协议提供对 URL 标识资源的访问。加载过程是异步的,所以 App 可以保持响应并当数据到达或出错时进行处理。 17 | 18 | 使用 [URLSession](https://developer.apple.com/documentation/foundation/urlsession) 实例可以创建一个或多个 [URLSessionTask](https://developer.apple.com/documentation/foundation/urlsessiontask) 实例,来抓取并返回数据给 App、下载文件、或者上传数据和文件到远程地址。使用 [URLSessionConfiguration](https://developer.apple.com/documentation/foundation/urlsessionconfiguration) 对象可以配置会话(Session),可以控制类似如何使用缓存和 Cookie 的行为、以及是否允许蜂窝网络连接。 19 | 20 | 一个会话可以重复地创建任务。举个例子,浏览器可能有分隔的会话以区分普通和隐私浏览,隐私会话将不缓存数据。图 1 展示了不同配置的两种会话可以创建许多任务。 21 | 22 | ![图 1 为 URL 会话创建任务](1.png) 23 | 24 | 1. 默认浏览:URLSession [默认配置] -> URLSessionDataTask 25 | 2. 隐私浏览:URLSession [临时配置] -> URLSessionDataTask 26 | 27 | 为了接收定期的更新(或错误),每个会话都与一个代理关联。默认代理将调用提供的回调 Block;如果选择提供自定义的代理,该 Block 不再调用。 28 | 29 | 通过配置 App 运行在后台时的会话,即可当 App 被挂起时,系统可以代替其下载数据并唤起 App 以分发结果。 30 | 31 | ## 话题 32 | 33 | ### 第一步 34 | 35 | 配置并创建会话,并用来创建与 URL 交互的任务。 36 | 37 | - [取回网页数据到内存](https://developer.apple.com/documentation/foundation/url_loading_system/fetching_website_data_into_memory) 38 | - 通过从 URL 会话创建数据任务来直接用内存接收数据。 39 | - [`class URLSession`](https://developer.apple.com/documentation/foundation/urlsession) 40 | - 定位一组相关网络数据传输任务的对象。 41 | - [`class URLSessionTask`](https://developer.apple.com/documentation/foundation/urlsessiontask) 42 | - 在 URL 会话中执行类似下载特定资源的任务。 43 | 44 | ### 请求与响应 45 | 46 | - [`struct URLRequest`](https://developer.apple.com/documentation/foundation/urlrequest) 47 | - 不依赖协议或 URL Scheme 的加载请求。 48 | - [`class URLResponse`](https://developer.apple.com/documentation/foundation/urlresponse) 49 | - 与 URL 加载请求响应有关的元数据,不依赖协议或 URL Scheme。 50 | - [`class HTTPURLResponse`](https://developer.apple.com/documentation/foundation/httpurlresponse) 51 | - 与 HTTP 协议 URL 加载请求响应有关的元数据。 52 | 53 | ### 上传 54 | 55 | - [上传数据到网站](https://developer.apple.com/documentation/foundation/url_loading_system/uploading_data_to_a_website) 56 | - 从 App 发送数据到服务器。 57 | - [上传数据流](https://developer.apple.com/documentation/foundation/url_loading_system/uploading_streams_of_data) 58 | - 向服务器发送数据流。 59 | 60 | ### 下载 61 | 62 | - [从网站下载文件](https://developer.apple.com/documentation/foundation/url_loading_system/downloading_files_from_websites) 63 | - 直接下载文件到文件系统。 64 | - [暂停和恢复下载](https://developer.apple.com/documentation/foundation/url_loading_system/pausing_and_resuming_downloads) 65 | - 允许用户无需重新开始的恢复下载。 66 | - [后台下载文件](https://developer.apple.com/documentation/foundation/url_loading_system/downloading_files_in_the_background) 67 | - 创建当 App 不活跃时的下载任务。 68 | 69 | ### 缓存行为 70 | 71 | - [访问缓存数据](https://developer.apple.com/documentation/foundation/url_loading_system/accessing_cached_data) 72 | - 控制 URL 请求如何使用原先的缓存数据。 73 | - [`class CachedURLResponse`](https://developer.apple.com/documentation/foundation/cachedurlresponse) 74 | - URL 请求的缓存响应。 75 | - [`class URLCache`](https://developer.apple.com/documentation/foundation/urlcache) 76 | - 映射 URL 请求到缓存的响应对象。 77 | 78 | ### 身份验证与资格 79 | 80 | - [处理身份验证校验](https://developer.apple.com/documentation/foundation/url_loading_system/handling_an_authentication_challenge) 81 | - 当服务器要求 URL 请求进行身份验证时的合适响应。 82 | - [`class URLAuthenticationChallenge`](https://developer.apple.com/documentation/foundation/urlauthenticationchallenge) 83 | - 来自需要客户端身份验证的服务器校验。 84 | - [`class URLCredential`](https://developer.apple.com/documentation/foundation/urlcredential) 85 | - 由特定凭证类型的信息和持久化存储使用的类型(如果存在)组成的身份验证凭证。 86 | - [`class URLCredentialStorage`](https://developer.apple.com/documentation/foundation/urlcredentialstorage) 87 | - 共享凭证缓存管理。 88 | - [`class URLProtectionSpace`](https://developer.apple.com/documentation/foundation/urlprotectionspace) 89 | - 需要认证的服务器或者服务器的某个区域,或称为领域(Realm)。 90 | 91 | ### Cookies 92 | 93 | - [`class HTTPCookie`](https://developer.apple.com/documentation/foundation/httpcookie) 94 | - HTTP Cookie 的代表。 95 | - [`class HTTPCookieStorage`](https://developer.apple.com/documentation/foundation/httpcookiestorage) 96 | - 管理 Cookie 存储的容器。 97 | 98 | ### 错误 99 | 100 | - [`struct URLError`](https://developer.apple.com/documentation/foundation/urlerror) 101 | - URL 加载 API 返回的错误码。 102 | - [URL 加载系统错误信息键](https://developer.apple.com/documentation/foundation/url_loading_system/url_loading_system_error_info_keys) 103 | - 从 URL 加载 API 产生的错误对象的用户信息字典中识别这些键。 104 | 105 | ### 遗留 106 | 107 | - [遗留 URL 加载系统](https://developer.apple.com/documentation/foundation/url_loading_system/legacy_url_loading_systems) 108 | - 将代码迁移远离使用这些旧对象。 109 | 110 | ## 参阅 111 | 112 | ### 网络 113 | 114 | #### [Bonjour](https://developer.apple.com/documentation/foundation/bonjour) 115 | 116 | - 指便于在本地网络发现的服务,或者由其他发现的服务。 117 | -------------------------------------------------------------------------------- /Posts/Translation/Uncovering_SourceKit/1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Translation/Uncovering_SourceKit/1.jpeg -------------------------------------------------------------------------------- /Posts/Translation/Uncovering_SourceKit/2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Translation/Uncovering_SourceKit/2.jpeg -------------------------------------------------------------------------------- /Posts/Translation/Uncovering_SourceKit/3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Translation/Uncovering_SourceKit/3.jpeg -------------------------------------------------------------------------------- /Posts/Translation/Uncovering_SourceKit/4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Translation/Uncovering_SourceKit/4.jpeg -------------------------------------------------------------------------------- /Posts/Translation/Uncovering_SourceKit/5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Translation/Uncovering_SourceKit/5.jpeg -------------------------------------------------------------------------------- /Posts/Translation/Uncovering_SourceKit/6.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Translation/Uncovering_SourceKit/6.jpeg -------------------------------------------------------------------------------- /Posts/Translation/Uncovering_SourceKit/7.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Translation/Uncovering_SourceKit/7.jpeg -------------------------------------------------------------------------------- /Posts/Translation/Uncovering_SourceKit/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/Perspective/d77eec6c5c84ca161b0e128c41af6b6722021195/Posts/Translation/Uncovering_SourceKit/8.png -------------------------------------------------------------------------------- /Posts/Translation/Uncovering_SourceKit/README.md: -------------------------------------------------------------------------------- 1 | # Translation - [译]起底 SourceKit 2 | 3 | 作者 | 发表时间 | 原文链接 4 | --- | --- | --- 5 | JP Simard | 20140706 | [https://www.jpsim.com/uncovering-sourcekit/](https://www.jpsim.com/uncovering-sourcekit/) 6 | 7 | > 为了支持一门[奇特的新编程语言](http://developer.apple.com/swift)(译者注:即 Swift),漂亮的[实时 IDE](https://developer.apple.com/library/prerelease/ios/recipes/xcode_help-source_editor/ExploringandEvaluatingSwiftCodeinaPlayground/ExploringandEvaluatingSwiftCodeinaPlayground.html) 特性,以及令人印象深刻的[跨语言协同性](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html)(译者注:即 Swift 与 Obj-C),Apple 不得不开发一些新的底层工具。这里我们将专注于 SourceKit,Xcode 背后的功臣。 8 | 9 | ![SourceKitSidekick 暂时披着披肩](1.jpeg) 10 | 11 | ## 什么是 SourceKit? 12 | 13 | SourceKit 是一套工具集,使得大多数 Swift 源代码层面的操作特性得以支持,例如源代码解析、语法高亮、排版(typesetting)、自动补全、跨语言头文件生成,等等。 14 | 15 | ## 架构 16 | 17 | 传统上,Xcode 在运行时跑着其编译器([Clang](http://clang.llvm.org/)),即意味着编译器将可能在任何时候崩溃,IDE 同样。 18 | 19 | ![Xcode 架构示意图](2.jpeg) 20 | 21 | 更有甚者,Xcode 容易唤起编译器进行成千上万次解析、高亮、以及排版源代码,所有这一切都在用户键入「⌘ + B」之前。这是因为不像大多数编辑器(Vim/Sublime/...),Xcode 并不使用正则表达式解析源代码,而是使用 Clang 强大的(也更加复杂的)解析器(parser)和标记器(tokenizer)。 22 | 23 | 庆幸的是,Xcode 6 中的 Swift 移除了该特性1,合并所有源代码操作特性至一个独立的进程,并和 Xcode 通过 [XPC](https://developer.apple.com/library/mac/documentation/macosx/conceptual/bpsystemstartup/chapters/CreatingXPCServices.html) 交流:`sourcekitd`。无论 Xcode 6 何时加载任何 Swift 代码,该 XPC 守护进程将被启动。 24 | 25 | ![如果每次出现如图情况时 Xcode 都会崩溃,生活将变得痛苦不堪](3.jpeg) 26 | 27 | ## Xcode 如何使用 SourceKit 28 | 29 | 因为 SourceKit 是一个私有且无文档的工具,我们需要获得一些小点子来学习如何使用它。通过设定 `SOURCEKIT_LOGGING`2 环境变量,Xcode 将记录 SourceKit 与 `stdout` 间的通信,允许我们观察到它们的实时通信。这就是如何发现本文中的许多命令。 30 | 31 | ## 统一符号解析 32 | 33 | SourceKit 借助 Clang 中称作 USR(Unified Symbol Resolution,即统一符号解析)的特性,为源代码令牌(token,例如类,属性,方法等)对应一个唯一标识符。这使得你可以使用 「⌘ + 点击」Xcode 编辑器中任何一处令牌,即可以导航至其定义处。USR 现在甚至更加强大了,可以跨语言(Swift/Obj-C)统一一个代表。 34 | 35 | ![运作中的 USR](4.jpeg) 36 | 37 | 为了从一个 Swift 文件(以及其位置)中打印 USR,你可以运行以下命令: 38 | 39 | ``` 40 | $ xcrun swift-ide-test -print-usrs -source-filename=Musician.swift 41 | 10:7 s:C14swift_ide_test8Musician 42 | 14:9 s:vC14swift_ide_test8Musician4nameSS 43 | 19:9 s:vC14swift_ide_test8Musician9birthyearSu 44 | 33:5 s:FC14swift_ide_test8MusiciancFMS0_FT4nameSS9birthyearSu_S0_ 45 | 33:10 s:vFC14swift_ide_test8MusiciancFMS0_FT4nameSS9birthyearSu_S0_L_4nameSS 46 | 33:24 s:vFC14swift_ide_test8MusiciancFMS0_FT4nameSS9birthyearSu_S0_L_9birthyearSu 47 | 34:9 s:vFC14swift_ide_test8MusiciancFMS0_FT4nameSS9birthyearSu_S0_L_4selfS0_ 48 | 34:21 s:vFC14swift_ide_test8MusiciancFMS0_FT4nameSS9birthyearSu_S0_L_4nameSS 49 | 35:9 s:vFC14swift_ide_test8MusiciancFMS0_FT4nameSS9birthyearSu_S0_L_4selfS0_ 50 | 35:26 s:vFC14swift_ide_test8MusiciancFMS0_FT4nameSS9birthyearSu_S0_L_9birthyearSu 51 | ``` 52 | 53 | ## Swift 头文件生成 54 | 55 | 在 Swift 中使用「⌘ + 点击」一个定义在 Obj-C 中令牌,Xcode 将会触发生成一个类 Swift 头文件。称其为类 Swift 是因为该生成的文件并非有效的 Swift3,但至少显示了等效于 Obj-C 令牌的 Swift 语法。 56 | 57 | ![左:原始 Obj-C 头文件,右:SourceKit 生成的类 Swift 版本](5.jpeg) 58 | 59 | ## 在命令行使用 SourceKit 60 | 61 | ![](6.jpeg) 62 | 63 | 主要有 3 个命令行工具允许和 SourceKit 交互:`sourcekitd-test`,`swift-ide-test`,以及 `swift`。 64 | 65 | 笔者编译了一个带有文档的 Shell 脚本,其运行了许多有用的命令,例如:语法高亮,接口生成,AST 解析,还原(demangling)等。 66 | 67 | 该脚本可在 GitHub 中获得:[GitHub Gist](https://gist.github.com/jpsim/13971c81445219db1c63#file-sourcekit_playground-sh)。 68 | 69 | ## 第三方使用 SourceKit 的工具 70 | 71 | 因为 SourceKit 独立于 Xcode 之外,使其可以利用以构建从 Swift IDE 到文档生成器等任何东西。 72 | 73 | ### Jazzy♪♫ 74 | 75 | ![](7.jpeg) 76 | 77 | [jazzy](https://github.com/realm/jazzy) 是一个命令行工具,可以为你的 Swift 或 Obj-C 项目生成文档。其利用 SourceKit 以获得从 Obj-C 定义令牌(例如类,属性,方法等)的 Swift 语法。 78 | 79 | ### SwiftEdit 80 | 81 | [SwiftEdit](https://github.com/jpsim/SwiftEdit) 是一款支持 Swift 文件语法高亮的概念型编辑器。 82 | 83 | ![](8.png) 84 | 85 | ## SourceKit 与你 86 | 87 | 我们刚刚初探了使用 SourceKit 的可能。这些工具可以做出来处理跨语言代码覆盖,或者提供支持 Swift 和 Obj-C 同时编辑的编辑器。希望本文能启发你利用 SourceKit 开发一些什么,并在这过程中改善我们的工具。 88 | 89 | - 注: 90 | 1. Obj-C 在 Xcode 6(Beta 2)中完全没有使用 SourceKit,仍保留了 Xcode 传统的运行中 Clang 架构。我预计在 Xcode 6 GM 前能有所改变。 91 | 2. 为了 SourceKit 打印日志,使用以下命令启动 Xcode `export SOURCEKIT_LOGGING=3 && /Applications/Xcode6-Beta2.app/Contents/MacOS/Xcode`。 92 | 3. 猜测:我预计一旦编程语言拥有访问控制机制,私有 Swift 模块暴露公有接口将使用相似的语法。 93 | 94 | --- 95 | 96 | ## Reference 97 | 98 | - [apple/swift/tools/SourceKit/](https://github.com/apple/swift/tree/master/tools/SourceKit) 99 | - [SourceKit and You - by JP Simard](https://academy.realm.io/posts/appbuilders-jp-simard-sourcekit/) 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Perspective 2 | 3 | > For English, please visit: [kingcos@medium](http://medium.com/@kingcos). 4 | > 5 | > Perspective,即透视。知道 CSAPP 这本书的同学应该对「Perspective」这个单词不陌生。笔者希望下面的文章能够清晰、透彻地讲清楚所要表述的内容,但个人也深知其不易,如有错误或纰漏,望您积极提出~ 6 | 7 | ![Blog-Perspective Mind Map](Blog-Perspective.png) 8 | 9 | ## Focus 10 | 11 | > Focus,即专注。笔者希望可以尽力将一些不是那么透彻的点通过 Demo 和源代码而看到其本质。由于国内软件开发仍很大程度依赖国外的语言、知识,部分术语会在文中首次提及时标注英文,这样的目的也是为了尽可能减少歧义。 12 | 13 | - [浅谈 Swift 中的属性(Property)](https://github.com/kingcos/Perspective/issues/21) 14 | - [探究 UIViewController 生命周期](https://github.com/kingcos/Perspective/issues/22) 15 | - [浅谈 iOS 应用启动过程](https://github.com/kingcos/Perspective/issues/23) 16 | - [Swift 中的 Selector](https://github.com/kingcos/Perspective/issues/24) 17 | - [Swift 中的 @autoclosure](https://github.com/kingcos/Perspective/issues/5) 18 | - [Swift Evolution (4.2)](https://github.com/kingcos/Perspective/issues/11) 19 | - [谈谈 iOS 中的 `dyld_shared_cache`](https://github.com/kingcos/Perspective/issues/55) 20 | - [Xcode 中的 Link Map 文件](https://github.com/kingcos/Perspective/issues/75) 21 | 22 | ## Practice 23 | 24 | > Practice,即实践。笔者将会把网上各处的知识点进行实际的代码总结、扩展。文章将着重 Demo,非核心相关的内容将以链接形式放置在文末供读者参考、延伸。 25 | 26 | - [从 0 开始使用 Docker 快速搭建 Hadoop 集群环境](https://github.com/kingcos/Perspective/issues/25) 27 | - [在 Swift 中对集合类型元素的弱引用](https://github.com/kingcos/Perspective/issues/6) 28 | - [iOS 项目持续集成实践(一)](https://github.com/kingcos/Perspective/issues/15) 29 | - iOS 多线程技术实践 30 | - [pthreads]() 31 | 32 | ## Promotion 33 | 34 | > Promotion,即提升。 35 | 36 | ## Studying 37 | 38 | > Studying,即钻研。笔者将分享个人的读书或浏览视频等所收获的心得、笔记。 39 | 40 | - [ICS 15-213](/Posts/Studying/ICS_15-213) 41 | - [Mac OS X and iOS Internals](/Posts/Studying/MacOSX_and_iOS_Internals) 42 | - [Programming from the Ground Up](/Posts/Studying/Programming_from_the_Ground_Up) 43 | - [Effective Objective-C 2.0](/Posts/Studying/Effective_Objective-C_2.0) 44 | - WWDC 17 45 | - [102 - Platform State of the Union](https://github.com/kingcos/Perspective/issues/26) 46 | - [819 - Designing for a Global Audience](https://github.com/kingcos/Perspective/issues/27) 47 | - [822 - App Icon Design](https://github.com/kingcos/Perspective/issues/28) 48 | - [823 - Designing Glyphs](https://github.com/kingcos/Perspective/issues/29) 49 | 50 | ## Tips 51 | 52 | > Tips,即提示。笔者将三言两语简述解决方案,延伸部分供读者自行参考、查阅。 53 | 54 | - [简单管理多版本 JDK](https://github.com/kingcos/Perspective/issues/7) 55 | - [使用 Homebrew 安装 MySQL](https://github.com/kingcos/Perspective/issues/8) 56 | - [Supervisor 的安装与基本使用](https://github.com/kingcos/Perspective/issues/9) 57 | - [使用 Homebrew 安装 Jenkins](https://github.com/kingcos/Perspective/issues/10) 58 | - [Xcode 10 beta 趟坑](https://github.com/kingcos/Perspective/issues/13) 59 | - [iOS 开发问题解决集锦](https://github.com/kingcos/Perspective/issues/16) 60 | - [在 macOS 上进行直播推流](https://github.com/kingcos/Perspective/issues/19) 61 | - [将树莓派作为 AirPlay 音频服务器](https://github.com/kingcos/Perspective/issues/20) 62 | - [使用 usbmuxd 连接 iPhone](https://github.com/kingcos/Perspective/issues/54) 63 | - [Swift 源代码中的 GYB](https://github.com/kingcos/Perspective/issues/62) 64 | - [将 Obj-C 代码翻译为 C++ 代码](https://github.com/kingcos/Perspective/issues/72) 65 | - [Obj-C 中的重载与重写](https://github.com/kingcos/Perspective/issues/73) 66 | 67 | ## Translation 68 | 69 | > Translation,即翻译。笔者将自己尽心翻译作品发布于此,限于笔者能力,如有错误,望读者可以纠正,笔者将十分感激。 70 | 71 | - [[译]起底 SourceKit](https://github.com/kingcos/Perspective/issues/12) 72 | - [[译]关于 App 启动顺序](https://github.com/kingcos/Perspective/issues/58) 73 | - [[译]为 App 执行一次性设置](https://github.com/kingcos/Perspective/issues/59) 74 | - [[译]URL 加载系统](https://github.com/kingcos/Perspective/issues/70) 75 | - [[译]在 Objective-C API 中指定可空性](https://github.com/kingcos/Perspective/issues/71) 76 | 77 | ## Thought 78 | 79 | > Thought,即思考。这里只是个人的胡言乱语[。](/Posts/Thought) 80 | 81 | ## Contact 82 | 83 | - E-mail: [2821836721v@gmail.com](mailto:2821836721v@gmail.com) 84 | - Twitter: [@kingcos_v](https://twitter.com/kingcos_v/) 85 | 86 | > 也欢迎您关注我的微博 [@萌面大道V](http://weibo.com/375975847) 87 | 88 | ## LICENSE 89 | 90 | - 该仓库所有内容不得在未经本人允许下进行任何形式的转载、修改等,一切相关事宜请直接联系我本人。 91 | - 谢谢您的配合! 92 | --------------------------------------------------------------------------------