From d644a1df82695fbb6a343a446fb4ec5f7b44503f Mon Sep 17 00:00:00 2001
From: pro648 <AugSpan@gmail.com>
Date: Mon, 25 Jan 2021 20:11:45 +0800
Subject: [PATCH] =?UTF-8?q?KVC=E3=80=81KVO=E7=9A=84=E6=9C=AC=E8=B4=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../project.pbxproj"                          | 387 ++++++++++++++++++
 .../contents.xcworkspacedata"                 |   7 +
 .../AppDelegate.h"                            |  14 +
 .../AppDelegate.m"                            |  40 ++
 .../AccentColor.colorset/Contents.json"       |  11 +
 .../AppIcon.appiconset/Contents.json"         |  98 +++++
 .../Assets.xcassets/Contents.json"            |   6 +
 .../Base.lproj/LaunchScreen.storyboard"       |  25 ++
 .../Base.lproj/Main.storyboard"               |  24 ++
 .../Info.plist"                               |  66 +++
 .../KVC/Observer.h"                           |  16 +
 .../KVC/Observer.m"                           |  16 +
 .../KVC/Person.h"                             |  31 ++
 .../KVC/Person.m"                             |  51 +++
 .../KVO/Child.h"                              |  18 +
 .../KVO/Child.m"                              |  33 ++
 .../KVO/NSKVONotifying_Child.h"               |  16 +
 .../KVO/NSKVONotifying_Child.m"               |  40 ++
 .../SceneDelegate.h"                          |  15 +
 .../SceneDelegate.m"                          |  57 +++
 .../ViewController.h"                         |  14 +
 .../ViewController.m"                         | 148 +++++++
 .../main.m"                                   |  18 +
 .../README.md"                                |  18 +
 README.md                                     |   1 +
 25 files changed, 1170 insertions(+)
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250.xcodeproj/project.pbxproj"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250.xcodeproj/project.xcworkspace/contents.xcworkspacedata"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/AppDelegate.h"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/AppDelegate.m"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/AccentColor.colorset/Contents.json"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/AppIcon.appiconset/Contents.json"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/Contents.json"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Base.lproj/LaunchScreen.storyboard"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Base.lproj/Main.storyboard"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Info.plist"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Observer.h"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Observer.m"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Person.h"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Person.m"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/Child.h"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/Child.m"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/NSKVONotifying_Child.h"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/NSKVONotifying_Child.m"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/SceneDelegate.h"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/SceneDelegate.m"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/ViewController.h"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/ViewController.m"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/main.m"
 create mode 100644 "KVC&KVO\347\232\204\346\234\254\350\264\250/README.md"

diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250.xcodeproj/project.pbxproj" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250.xcodeproj/project.pbxproj"
new file mode 100644
index 0000000..7c973b4
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250.xcodeproj/project.pbxproj"
@@ -0,0 +1,387 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 50;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		0D5B188825B9273500F1D301 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D5B188725B9273500F1D301 /* AppDelegate.m */; };
+		0D5B188B25B9273500F1D301 /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D5B188A25B9273500F1D301 /* SceneDelegate.m */; };
+		0D5B188E25B9273500F1D301 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D5B188D25B9273500F1D301 /* ViewController.m */; };
+		0D5B189125B9273500F1D301 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0D5B188F25B9273500F1D301 /* Main.storyboard */; };
+		0D5B189325B9273600F1D301 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D5B189225B9273600F1D301 /* Assets.xcassets */; };
+		0D5B189625B9273600F1D301 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0D5B189425B9273600F1D301 /* LaunchScreen.storyboard */; };
+		0D5B189925B9273600F1D301 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D5B189825B9273600F1D301 /* main.m */; };
+		0D5B18A225B9275000F1D301 /* Child.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D5B18A125B9275000F1D301 /* Child.m */; };
+		0DB67EF025BE7670007C5DCF /* Person.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DB67EEF25BE7670007C5DCF /* Person.m */; };
+		0DB67EF525BE7679007C5DCF /* Observer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DB67EF425BE7679007C5DCF /* Observer.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		0D5B188325B9273500F1D301 /* KVC&KVO的本质.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "KVC&KVO的本质.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+		0D5B188625B9273500F1D301 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+		0D5B188725B9273500F1D301 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+		0D5B188925B9273500F1D301 /* SceneDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SceneDelegate.h; sourceTree = "<group>"; };
+		0D5B188A25B9273500F1D301 /* SceneDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SceneDelegate.m; sourceTree = "<group>"; };
+		0D5B188C25B9273500F1D301 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
+		0D5B188D25B9273500F1D301 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
+		0D5B189025B9273500F1D301 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+		0D5B189225B9273600F1D301 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+		0D5B189525B9273600F1D301 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+		0D5B189725B9273600F1D301 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		0D5B189825B9273600F1D301 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		0D5B18A025B9275000F1D301 /* Child.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Child.h; sourceTree = "<group>"; };
+		0D5B18A125B9275000F1D301 /* Child.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Child.m; sourceTree = "<group>"; };
+		0D9A098825B9805500AE5BE3 /* NSKVONotifying_Child.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSKVONotifying_Child.h; sourceTree = "<group>"; };
+		0D9A098925B9805500AE5BE3 /* NSKVONotifying_Child.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSKVONotifying_Child.m; sourceTree = "<group>"; };
+		0DB67EEE25BE7670007C5DCF /* Person.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Person.h; sourceTree = "<group>"; };
+		0DB67EEF25BE7670007C5DCF /* Person.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Person.m; sourceTree = "<group>"; };
+		0DB67EF325BE7679007C5DCF /* Observer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Observer.h; sourceTree = "<group>"; };
+		0DB67EF425BE7679007C5DCF /* Observer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Observer.m; sourceTree = "<group>"; };
+		0DB67EF825BEE9D3007C5DCF /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		0D5B188025B9273500F1D301 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		0D5B187A25B9273500F1D301 = {
+			isa = PBXGroup;
+			children = (
+				0DB67EF825BEE9D3007C5DCF /* README.md */,
+				0D5B188525B9273500F1D301 /* KVC&KVO的本质 */,
+				0D5B188425B9273500F1D301 /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		0D5B188425B9273500F1D301 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				0D5B188325B9273500F1D301 /* KVC&KVO的本质.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		0D5B188525B9273500F1D301 /* KVC&KVO的本质 */ = {
+			isa = PBXGroup;
+			children = (
+				0D5B188625B9273500F1D301 /* AppDelegate.h */,
+				0D5B188725B9273500F1D301 /* AppDelegate.m */,
+				0D5B188925B9273500F1D301 /* SceneDelegate.h */,
+				0D5B188A25B9273500F1D301 /* SceneDelegate.m */,
+				0D5B188C25B9273500F1D301 /* ViewController.h */,
+				0D5B188D25B9273500F1D301 /* ViewController.m */,
+				0DB67EED25BE7625007C5DCF /* KVC */,
+				0DB67EEC25BE7619007C5DCF /* KVO */,
+				0D5B188F25B9273500F1D301 /* Main.storyboard */,
+				0D5B189225B9273600F1D301 /* Assets.xcassets */,
+				0D5B189425B9273600F1D301 /* LaunchScreen.storyboard */,
+				0D5B189725B9273600F1D301 /* Info.plist */,
+				0D5B189825B9273600F1D301 /* main.m */,
+			);
+			path = "KVC&KVO的本质";
+			sourceTree = "<group>";
+		};
+		0DB67EEC25BE7619007C5DCF /* KVO */ = {
+			isa = PBXGroup;
+			children = (
+				0D5B18A025B9275000F1D301 /* Child.h */,
+				0D5B18A125B9275000F1D301 /* Child.m */,
+				0D9A098825B9805500AE5BE3 /* NSKVONotifying_Child.h */,
+				0D9A098925B9805500AE5BE3 /* NSKVONotifying_Child.m */,
+			);
+			path = KVO;
+			sourceTree = "<group>";
+		};
+		0DB67EED25BE7625007C5DCF /* KVC */ = {
+			isa = PBXGroup;
+			children = (
+				0DB67EEE25BE7670007C5DCF /* Person.h */,
+				0DB67EEF25BE7670007C5DCF /* Person.m */,
+				0DB67EF325BE7679007C5DCF /* Observer.h */,
+				0DB67EF425BE7679007C5DCF /* Observer.m */,
+			);
+			path = KVC;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		0D5B188225B9273500F1D301 /* KVC&KVO的本质 */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 0D5B189C25B9273600F1D301 /* Build configuration list for PBXNativeTarget "KVC&KVO的本质" */;
+			buildPhases = (
+				0D5B187F25B9273500F1D301 /* Sources */,
+				0D5B188025B9273500F1D301 /* Frameworks */,
+				0D5B188125B9273500F1D301 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "KVC&KVO的本质";
+			productName = "KVC&KVO的本质";
+			productReference = 0D5B188325B9273500F1D301 /* KVC&KVO的本质.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		0D5B187B25B9273500F1D301 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 1230;
+				TargetAttributes = {
+					0D5B188225B9273500F1D301 = {
+						CreatedOnToolsVersion = 12.3;
+					};
+				};
+			};
+			buildConfigurationList = 0D5B187E25B9273500F1D301 /* Build configuration list for PBXProject "KVC&KVO的本质" */;
+			compatibilityVersion = "Xcode 9.3";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = 0D5B187A25B9273500F1D301;
+			productRefGroup = 0D5B188425B9273500F1D301 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				0D5B188225B9273500F1D301 /* KVC&KVO的本质 */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		0D5B188125B9273500F1D301 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				0D5B189625B9273600F1D301 /* LaunchScreen.storyboard in Resources */,
+				0D5B189325B9273600F1D301 /* Assets.xcassets in Resources */,
+				0D5B189125B9273500F1D301 /* Main.storyboard in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		0D5B187F25B9273500F1D301 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				0DB67EF025BE7670007C5DCF /* Person.m in Sources */,
+				0D5B188E25B9273500F1D301 /* ViewController.m in Sources */,
+				0D5B188825B9273500F1D301 /* AppDelegate.m in Sources */,
+				0DB67EF525BE7679007C5DCF /* Observer.m in Sources */,
+				0D5B189925B9273600F1D301 /* main.m in Sources */,
+				0D5B188B25B9273500F1D301 /* SceneDelegate.m in Sources */,
+				0D5B18A225B9275000F1D301 /* Child.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+		0D5B188F25B9273500F1D301 /* Main.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				0D5B189025B9273500F1D301 /* Base */,
+			);
+			name = Main.storyboard;
+			sourceTree = "<group>";
+		};
+		0D5B189425B9273600F1D301 /* LaunchScreen.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				0D5B189525B9273600F1D301 /* Base */,
+			);
+			name = LaunchScreen.storyboard;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		0D5B189A25B9273600F1D301 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 14.3;
+				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+				MTL_FAST_MATH = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+			};
+			name = Debug;
+		};
+		0D5B189B25B9273600F1D301 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 14.3;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				MTL_FAST_MATH = YES;
+				SDKROOT = iphoneos;
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
+		0D5B189D25B9273600F1D301 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+				CODE_SIGN_STYLE = Automatic;
+				INFOPLIST_FILE = "KVC&KVO的本质/Info.plist";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = "pro648.KVC-KVO---";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Debug;
+		};
+		0D5B189E25B9273600F1D301 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+				CODE_SIGN_STYLE = Automatic;
+				INFOPLIST_FILE = "KVC&KVO的本质/Info.plist";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = "pro648.KVC-KVO---";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		0D5B187E25B9273500F1D301 /* Build configuration list for PBXProject "KVC&KVO的本质" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				0D5B189A25B9273600F1D301 /* Debug */,
+				0D5B189B25B9273600F1D301 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		0D5B189C25B9273600F1D301 /* Build configuration list for PBXNativeTarget "KVC&KVO的本质" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				0D5B189D25B9273600F1D301 /* Debug */,
+				0D5B189E25B9273600F1D301 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 0D5B187B25B9273500F1D301 /* Project object */;
+}
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250.xcodeproj/project.xcworkspace/contents.xcworkspacedata" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250.xcodeproj/project.xcworkspace/contents.xcworkspacedata"
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250.xcodeproj/project.xcworkspace/contents.xcworkspacedata"
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:">
+   </FileRef>
+</Workspace>
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/AppDelegate.h" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/AppDelegate.h"
new file mode 100644
index 0000000..8c19187
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/AppDelegate.h"
@@ -0,0 +1,14 @@
+//
+//  AppDelegate.h
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//  
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+
+@end
+
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/AppDelegate.m" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/AppDelegate.m"
new file mode 100644
index 0000000..652dbfe
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/AppDelegate.m"
@@ -0,0 +1,40 @@
+//
+//  AppDelegate.m
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//  
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+    // Override point for customization after application launch.
+    return YES;
+}
+
+
+#pragma mark - UISceneSession lifecycle
+
+
+- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
+    // Called when a new scene session is being created.
+    // Use this method to select a configuration to create the new scene with.
+    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
+}
+
+
+- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
+    // Called when the user discards a scene session.
+    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
+    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
+}
+
+
+@end
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/AccentColor.colorset/Contents.json" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/AccentColor.colorset/Contents.json"
new file mode 100644
index 0000000..eb87897
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/AccentColor.colorset/Contents.json"
@@ -0,0 +1,11 @@
+{
+  "colors" : [
+    {
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/AppIcon.appiconset/Contents.json" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/AppIcon.appiconset/Contents.json"
new file mode 100644
index 0000000..9221b9b
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/AppIcon.appiconset/Contents.json"
@@ -0,0 +1,98 @@
+{
+  "images" : [
+    {
+      "idiom" : "iphone",
+      "scale" : "2x",
+      "size" : "20x20"
+    },
+    {
+      "idiom" : "iphone",
+      "scale" : "3x",
+      "size" : "20x20"
+    },
+    {
+      "idiom" : "iphone",
+      "scale" : "2x",
+      "size" : "29x29"
+    },
+    {
+      "idiom" : "iphone",
+      "scale" : "3x",
+      "size" : "29x29"
+    },
+    {
+      "idiom" : "iphone",
+      "scale" : "2x",
+      "size" : "40x40"
+    },
+    {
+      "idiom" : "iphone",
+      "scale" : "3x",
+      "size" : "40x40"
+    },
+    {
+      "idiom" : "iphone",
+      "scale" : "2x",
+      "size" : "60x60"
+    },
+    {
+      "idiom" : "iphone",
+      "scale" : "3x",
+      "size" : "60x60"
+    },
+    {
+      "idiom" : "ipad",
+      "scale" : "1x",
+      "size" : "20x20"
+    },
+    {
+      "idiom" : "ipad",
+      "scale" : "2x",
+      "size" : "20x20"
+    },
+    {
+      "idiom" : "ipad",
+      "scale" : "1x",
+      "size" : "29x29"
+    },
+    {
+      "idiom" : "ipad",
+      "scale" : "2x",
+      "size" : "29x29"
+    },
+    {
+      "idiom" : "ipad",
+      "scale" : "1x",
+      "size" : "40x40"
+    },
+    {
+      "idiom" : "ipad",
+      "scale" : "2x",
+      "size" : "40x40"
+    },
+    {
+      "idiom" : "ipad",
+      "scale" : "1x",
+      "size" : "76x76"
+    },
+    {
+      "idiom" : "ipad",
+      "scale" : "2x",
+      "size" : "76x76"
+    },
+    {
+      "idiom" : "ipad",
+      "scale" : "2x",
+      "size" : "83.5x83.5"
+    },
+    {
+      "idiom" : "ios-marketing",
+      "scale" : "1x",
+      "size" : "1024x1024"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/Contents.json" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/Contents.json"
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Assets.xcassets/Contents.json"
@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Base.lproj/LaunchScreen.storyboard" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Base.lproj/LaunchScreen.storyboard"
new file mode 100644
index 0000000..865e932
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Base.lproj/LaunchScreen.storyboard"
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--View Controller-->
+        <scene sceneID="EHf-IW-A2E">
+            <objects>
+                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                        <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="53" y="375"/>
+        </scene>
+    </scenes>
+</document>
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Base.lproj/Main.storyboard" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Base.lproj/Main.storyboard"
new file mode 100644
index 0000000..808a21c
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Base.lproj/Main.storyboard"
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--View Controller-->
+        <scene sceneID="tne-QT-ifu">
+            <objects>
+                <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
+                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                        <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
+    </scenes>
+</document>
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Info.plist" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Info.plist"
new file mode 100644
index 0000000..72bf2c4
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/Info.plist"
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UIApplicationSceneManifest</key>
+	<dict>
+		<key>UIApplicationSupportsMultipleScenes</key>
+		<false/>
+		<key>UISceneConfigurations</key>
+		<dict>
+			<key>UIWindowSceneSessionRoleApplication</key>
+			<array>
+				<dict>
+					<key>UISceneConfigurationName</key>
+					<string>Default Configuration</string>
+					<key>UISceneDelegateClassName</key>
+					<string>SceneDelegate</string>
+					<key>UISceneStoryboardFile</key>
+					<string>Main</string>
+				</dict>
+			</array>
+		</dict>
+	</dict>
+	<key>UIApplicationSupportsIndirectInputEvents</key>
+	<true/>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIMainStoryboardFile</key>
+	<string>Main</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>armv7</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+</dict>
+</plist>
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Observer.h" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Observer.h"
new file mode 100644
index 0000000..bdd60a6
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Observer.h"
@@ -0,0 +1,16 @@
+//
+//  Observer.h
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//  
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface Observer : NSObject
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Observer.m" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Observer.m"
new file mode 100644
index 0000000..4f985b2
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Observer.m"
@@ -0,0 +1,16 @@
+//
+//  Observer.m
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//  
+
+#import "Observer.h"
+
+@implementation Observer
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
+    NSLog(@"%s - %@", __PRETTY_FUNCTION__, change);
+}
+
+@end
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Person.h" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Person.h"
new file mode 100644
index 0000000..90a5a80
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Person.h"
@@ -0,0 +1,31 @@
+//
+//  Person.h
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//  
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface Person : NSObject
+{
+    @public
+    // 如果没有set方法,按照下面顺序查找。
+//    int _age;
+    int _isAge;
+    int age;
+    int isAge;
+}
+
+// 如果没有setAge方法,但有上述成员变量,就会触发KVO。KVO内部实现了willChangeValueForKey didChangeValueForKey。
+
+//@property (nonatomic, assign) int age;
+
+// 如果是只读的,则会查看accessInstanceMethodDirectly返回值,进而决定是否查看成员变量。
+//@property (nonatomic, assign, readonly) int age;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Person.m" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Person.m"
new file mode 100644
index 0000000..1a2e7b6
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC/Person.m"
@@ -0,0 +1,51 @@
+//
+//  Person.m
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//  
+
+#import "Person.h"
+
+@implementation Person
+
+// MARK: - setValue:forKey:
+
+//- (void)setAge:(int)age {
+//    _age = age;
+//    NSLog(@"%s %d", __PRETTY_FUNCTION__, age);
+//}
+//
+//- (void)_setAge:(int)age {
+//    _age = age;
+//    NSLog(@"%s %d", __PRETTY_FUNCTION__, age);
+//}
+
+// MARK: - valueForKey:
+
+- (int)getAge {
+    return 22;
+}
+
+// 没有访问器方法,是否运行直接访问变量。默认YES。
++ (BOOL)accessInstanceVariablesDirectly {
+    return YES;
+//    return NO;
+}
+
+// 可以验证内部实现了willChangeValueForKey: didChangeValueForKey:
+- (void)willChangeValueForKey:(NSString *)key {
+    [super willChangeValueForKey:key];
+    
+    NSLog(@"%s %@", __PRETTY_FUNCTION__, key);
+}
+
+- (void)didChangeValueForKey:(NSString *)key {
+    NSLog(@"%s - begin - %@", __PRETTY_FUNCTION__, key);
+    
+    [super didChangeValueForKey:key];
+    
+    NSLog(@"%s - end - %@", __PRETTY_FUNCTION__, key);
+}
+
+@end
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/Child.h" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/Child.h"
new file mode 100644
index 0000000..a903aec
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/Child.h"
@@ -0,0 +1,18 @@
+//
+//  Child.h
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/21.
+//  
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface Child : NSObject
+
+@property (nonatomic, assign) int age;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/Child.m" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/Child.m"
new file mode 100644
index 0000000..e031f54
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/Child.m"
@@ -0,0 +1,33 @@
+//
+//  Child.m
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/21.
+//  
+
+#import "Child.h"
+
+@implementation Child
+
+- (void)setAge:(int)age {
+    NSLog(@"begin - setAge:%d", age);
+    _age = age;
+    NSLog(@"end - setAge:%d", age);
+    
+//    NSLog(@"KVO是否通过重写setAge:方法实现?age:%d", age);
+}
+
+- (void)willChangeValueForKey:(NSString *)key {
+    NSLog(@"willChangeValueForKey: - begin");
+    [super willChangeValueForKey:key];
+    NSLog(@"willChangeValueForKey: - end");
+}
+
+// 验证didChangeValueForKey:调用了KVO
+- (void)didChangeValueForKey:(NSString *)key {
+    NSLog(@"didChangeValueForKey: - begin");
+    [super didChangeValueForKey:key];
+    NSLog(@"didChangeValueForKey: - end");
+}
+
+@end
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/NSKVONotifying_Child.h" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/NSKVONotifying_Child.h"
new file mode 100644
index 0000000..b6cf9f4
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/NSKVONotifying_Child.h"
@@ -0,0 +1,16 @@
+//
+//  NSKVONotifying_Child.h
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/21.
+//  
+
+#import "Child.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface NSKVONotifying_Child : Child
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/NSKVONotifying_Child.m" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/NSKVONotifying_Child.m"
new file mode 100644
index 0000000..06d899c
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/KVO/NSKVONotifying_Child.m"
@@ -0,0 +1,40 @@
+//
+//  NSKVONotifying_Child.m
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/21.
+//  
+
+#import "NSKVONotifying_Child.h"
+#import <objc/runtime.h>
+
+@implementation NSKVONotifying_Child
+
+//- (void)setAge:(int)age {
+//    _NSSetIntValueAndNotify();
+//}
+//
+//void _NSSetIntValueAndNotify() {
+//    [self willChangeValueForKey:@"age"];
+//    [super setAge:age];
+//    [self didChangeValueForKey:@"age"];
+//}
+//
+//- (void)didChangeValueForKey:(NSString *)key {
+//    // 通知监听器,key属性发生了改变。
+//    [observer observeValueForKeyPath:key ofObject:self change:nil context:nil];
+//}
+
+- (Class)class {
+    return class_getSuperclass(object_getClass(self));
+}
+
+- (void)dealloc {
+    // 执行清理工作
+}
+
+- (BOOL)isKVOA {
+    return YES;
+}
+
+@end
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/SceneDelegate.h" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/SceneDelegate.h"
new file mode 100644
index 0000000..5e6c9e8
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/SceneDelegate.h"
@@ -0,0 +1,15 @@
+//
+//  SceneDelegate.h
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//  
+
+#import <UIKit/UIKit.h>
+
+@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>
+
+@property (strong, nonatomic) UIWindow * window;
+
+@end
+
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/SceneDelegate.m" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/SceneDelegate.m"
new file mode 100644
index 0000000..7903564
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/SceneDelegate.m"
@@ -0,0 +1,57 @@
+//
+//  SceneDelegate.m
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//  
+
+#import "SceneDelegate.h"
+
+@interface SceneDelegate ()
+
+@end
+
+@implementation SceneDelegate
+
+
+- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
+    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
+    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
+    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
+}
+
+
+- (void)sceneDidDisconnect:(UIScene *)scene {
+    // Called as the scene is being released by the system.
+    // This occurs shortly after the scene enters the background, or when its session is discarded.
+    // Release any resources associated with this scene that can be re-created the next time the scene connects.
+    // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
+}
+
+
+- (void)sceneDidBecomeActive:(UIScene *)scene {
+    // Called when the scene has moved from an inactive state to an active state.
+    // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
+}
+
+
+- (void)sceneWillResignActive:(UIScene *)scene {
+    // Called when the scene will move from an active state to an inactive state.
+    // This may occur due to temporary interruptions (ex. an incoming phone call).
+}
+
+
+- (void)sceneWillEnterForeground:(UIScene *)scene {
+    // Called as the scene transitions from the background to the foreground.
+    // Use this method to undo the changes made on entering the background.
+}
+
+
+- (void)sceneDidEnterBackground:(UIScene *)scene {
+    // Called as the scene transitions from the foreground to the background.
+    // Use this method to save data, release shared resources, and store enough scene-specific state information
+    // to restore the scene back to its current state.
+}
+
+
+@end
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/ViewController.h" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/ViewController.h"
new file mode 100644
index 0000000..c4e3ef9
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/ViewController.h"
@@ -0,0 +1,14 @@
+//
+//  ViewController.h
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//  
+
+#import <UIKit/UIKit.h>
+
+@interface ViewController : UIViewController
+
+
+@end
+
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/ViewController.m" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/ViewController.m"
new file mode 100644
index 0000000..18df472
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/ViewController.m"
@@ -0,0 +1,148 @@
+//
+//  ViewController.m
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//
+//  详细介绍:https://github.com/pro648/tips/blob/master/sources/KVC%E3%80%81KVO%E7%9A%84%E6%9C%AC%E8%B4%A8.md
+
+#import "ViewController.h"
+#import "Child.h"
+#import <objc/runtime.h>
+#import "Person.h"
+#import "Observer.h"
+
+@interface ViewController ()
+
+@property (nonatomic, strong) Child *child1;
+@property (nonatomic, strong) Child *child2;
+@property (nonatomic, strong) Observer *observer;
+@property (nonatomic, strong) Person *person;
+
+@end
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    [self testKVO];
+    [self testKVC];
+}
+
+// MARK: - KVO
+
+- (void)testKVO {
+    self.child1 = [[Child alloc] init];
+    self.child1.age = 1;
+
+    self.child2 = [[Child alloc] init];
+    self.child2.age = 2;
+
+    // 打印添加观察者前实例对象的isa
+//    NSLog(@"添加Observer前 child1: %@ - child2: %@", object_getClass(self.child1), object_getClass(self.child2));
+
+    // 打印添加观察者前,打印setAge:具体实现。
+//    NSLog(@"添加Observer前 child1: %p - child2: %p", [self.child1 methodForSelector:@selector(setAge:)], [self.child2 methodForSelector:@selector(setAge:)]);
+
+    // 添加观察者
+    [self.child1 addObserver:self
+                  forKeyPath:@"age"
+                     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
+                     context:@"123context"];
+
+    // 打印添加观察者后实例对象的isa
+//    NSLog(@"添加Observer后 child1: %@ - child2: %@", object_getClass(self.child1), object_getClass(self.child2));
+
+    // 打印添加观察者后,打印setAge:具体实现。
+//    NSLog(@"添加Observer后 child1: %p - child2: %p", [self.child1 methodForSelector:@selector(setAge:)], [self.child2 methodForSelector:@selector(setAge:)]);
+
+    // 打印添加观察者后,child1、child2类对象中所有方法
+//    [self printMethodList:object_getClass(self.child1)];
+//    [self printMethodList:object_getClass(self.child2)];
+}
+
+// 观察到键值发生改变
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
+    NSLog(@"监听到 %@ 的 %@ 属性值发生改变 - %@ - %@", object, keyPath, change, context);
+}
+
+- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
+    [self.child1 setAge:11];
+
+    [self.child2 setAge:22];
+}
+
+- (void)printMethodList:(Class)cls {
+    unsigned int methodCount;
+    // 获取方法数组
+    Method *methodList = class_copyMethodList(cls, &methodCount);
+    
+    NSMutableString *name = [NSMutableString string];
+    for (int i=0; i<methodCount; ++i) {
+        // 获得方法
+        Method method = methodList[i];
+        // 获得方法名
+        NSString *methodName = NSStringFromSelector(method_getName(method));
+        
+        [name appendString:methodName];
+        [name appendString:@", "];
+    }
+    
+    // C语言中使用copy、create创建的对象需释放。
+    free(methodList);
+    NSLog(@"%@ %@", cls, name);
+}
+
+- (void)printIvarList:(Class)cls {
+    unsigned int ivarCount;
+    // 获取ivar数组
+    Ivar *ivarList = class_copyIvarList(cls, &ivarCount);
+    // 存储ivar名
+    NSMutableString *ivarNames = [NSMutableString string];
+    
+    // 遍历所有的ivar
+    for (int i=0; i<ivarCount; ++i) {
+        // 获得ivar
+        Ivar ivar = ivarList[i];
+        // 获得ivar名
+        NSString *methodName = [NSString stringWithUTF8String:ivar_getName(ivar)];
+        // 拼接ivar名
+        [ivarNames appendString:methodName];
+        [ivarNames appendString:@", "];
+    }
+    
+    // C语言中使用create、copy创建的对象,需释放。
+    free(ivarList);
+    NSLog(@"%@ %@", cls, ivarNames);
+}
+
+// MARK: - KVC
+
+- (void)testKVC {
+    self.observer = [[Observer alloc] init];
+    self.person = [[Person alloc] init];
+    
+    [self.person addObserver:self.observer
+                  forKeyPath:@"age"
+                     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
+                     context:NULL];
+    
+//    [self printIvarList:[Person class]];
+    [self.person setValue:@10 forKey:@"age"];
+    
+    NSLog(@"age: %@", [self.person valueForKey:@"age"]);
+    
+    NSLog(@"");
+    
+}
+
+- (void)dealloc {
+    // 移除观察者
+    [self.child1 removeObserver:self
+                     forKeyPath:@"age"];
+    [self.person removeObserver:self.observer
+                     forKeyPath:@"age"];
+}
+
+@end
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/main.m" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/main.m"
new file mode 100644
index 0000000..f8945fe
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/KVC&KVO\347\232\204\346\234\254\350\264\250/main.m"
@@ -0,0 +1,18 @@
+//
+//  main.m
+//  KVC&KVO的本质
+//
+//  Created by pro648 on 2021/1/24.
+//  
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+    NSString * appDelegateClassName;
+    @autoreleasepool {
+        // Setup code that might create autoreleased objects goes here.
+        appDelegateClassName = NSStringFromClass([AppDelegate class]);
+    }
+    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
+}
diff --git "a/KVC&KVO\347\232\204\346\234\254\350\264\250/README.md" "b/KVC&KVO\347\232\204\346\234\254\350\264\250/README.md"
new file mode 100644
index 0000000..f80f803
--- /dev/null
+++ "b/KVC&KVO\347\232\204\346\234\254\350\264\250/README.md"
@@ -0,0 +1,18 @@
+###  KVC、KVO的本质
+
+添加观察者后,KVO利用runtime生成一个`NSKVONOtifying_`子类,并重写set方法。修改属性值时触发KVO。
+
+![NSKVONotifying](https://raw.githubusercontent.com/pro648/tips/master/sources/images/21/KVO%26KVCNSKVONotifying_XXX.png)
+
+使用KVC设值时,`setValue:forKey:`原理如下:
+
+- 先查找`setKey:`、`_setKey:`方法,如果找到了,直接传递参数,调用方法;如果找不到,进入下一步。
+- 查看`accessInstanceVariableDirectly`方法返回值,如果返回`NO`,即不允许访问成员变量,则调用`setValue:forUndefinedKey:`方法,并抛出`NSUnknownKeyException`异常;如果返回`YES`,进入下一步。
+- 按照`_key`、`_isKey`、`key`、`isKey`顺序查找成员变量,如果找到了成员变量,直接赋值。如果找不到,则调用`setValue:forUndefinedKey:`方法,并抛出`NSUnknownKeyException`异常。
+
+![setValueForKey](https://raw.githubusercontent.com/pro648/tips/master/sources/images/21/KVO%26KVCsetValue.png)
+
+详细介绍查看下面文章:
+
+<https://github.com/pro648/tips/blob/master/sources/KVC、KVO的本质.md>
+
diff --git a/README.md b/README.md
index 8a45c3f..c3a2e9a 100755
--- a/README.md
+++ b/README.md
@@ -27,6 +27,7 @@ iOS学习进程中的demo汇总
 | GestureRecognizer         | [手势控制:点击、滑动、平移、捏合、旋转、长按、轻扫](https://github.com/pro648/tips/wiki/%E6%89%8B%E5%8A%BF%E6%8E%A7%E5%88%B6%EF%BC%9A%E7%82%B9%E5%87%BB%E3%80%81%E6%BB%91%E5%8A%A8%E3%80%81%E5%B9%B3%E7%A7%BB%E3%80%81%E6%8D%8F%E5%90%88%E3%80%81%E6%97%8B%E8%BD%AC%E3%80%81%E9%95%BF%E6%8C%89%E3%80%81%E8%BD%BB%E6%89%AB) |
 | IteratorPattern	| [迭代器模式 Iterator Pattern](https://github.com/pro648/tips/wiki/%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F-Iterator-Pattern)	|
 | KVC&KVODemo               | [KVC和KVO学习笔记](https://github.com/pro648/tips/wiki/KVC%E5%92%8CKVO%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0) |
+|	KVC&KVO原理	|	[KVC、KVO的本质](https://github.com/pro648/tips/blob/master/sources/KVC、KVO的本质.md)	|
 | KeyedArchiver             | [数据存储之归档解档 NSKeyedArchiver NSKeyedUnarchiver](https://github.com/pro648/tips/wiki/%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E4%B9%8B%E5%BD%92%E6%A1%A3%E8%A7%A3%E6%A1%A3-NSKeyedArchiver-NSKeyedUnarchiver) |
 | LinkedList	| [链表 LinkedList](https://github.com/pro648/tips/blob/master/sources/%E9%93%BE%E8%A1%A8%20LinkedList.md)	|
 | MementoPattern	| [备忘录模式 Memento Pattern](https://github.com/pro648/tips/wiki/%E5%A4%87%E5%BF%98%E5%BD%95%E6%A8%A1%E5%BC%8F-Memento-Pattern)|