{"data":{"post":{"title":"A Story of Implementing Aspect-Oriented Programming in Objective-C and Swift","subtitle":"","isPublished":true,"createdTime":"2019-03-01T00:00:00.000Z","lastModifiedTime":null,"license":null,"tags":["Swift","Objective-C","Aspect-Oriented Programming"],"category":"Programming","file":{"childMdx":{"excerpt":"Case Study: Intervening UIScrollView Instances's Pan Gesture Recognizer As we known,  UIScrollView…","code":{"body":"function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nconst layoutProps = {};\nreturn class MDXContent extends React.Component {\n  constructor(props) {\n    super(props);\n    this.layout = null;\n  }\n\n  render() {\n    const _this$props = this.props,\n          {\n      components\n    } = _this$props,\n          props = _objectWithoutProperties(_this$props, [\"components\"]);\n\n    return React.createElement(MDXTag, {\n      name: \"wrapper\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Case Study: Intervening UIScrollView Instances's Pan Gesture Recognizer`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `As we known, `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIScrollView`), ` translates pan gesture signals into\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `scrollViewDidXXX:`), ` messages and sends to its delegate, most of the time\nyou only have to understand the relationships between the pan gesture\nsignals and the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `scrollViewDidXXX:`), ` messages and then listen to these\nsignals in the delegate. But what if you want to intervene the pan gesture\nrecognizer's work? I mean, to intervene the handling of pan gesture's\nrecognition.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Here, if we don't modify the internal mechanism of `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIScrollView`), `, we\nhave to make a subclass.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIScrollView`), `'s pan gesture recognizer solidates its delegate to be the\nowning `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIScrollView`), ` instance itself. If you set its delegate to another\n\"man in-the-middle\", you would get a runtime exception. Most people would\ncome up with subclassing here, but what if you are expecting this\nmodification may affect some instances of subclasses inherited to\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIScrollView`), ` at some point?`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `In object-oriented programming paradigm, modifying the internal mechanism\nof an existed class is not encouraged. Since object-oriented programming\nbuilds upon continuously making `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `is-a`), ` assertions -- what a class do\nmake the reason why this class `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `is`), ` the class itself, then one of the\ncore concepts of object-oriented programming is to extend but not modify.\nModifying the internal mechanism of an existed class just breaks the\nparadigm. If you modified it, the `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `is-a`), ` assertion torn down and the\nfoundation of software architecture swinged.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `So, don't be cult of whatever-oriented programming forever. This time you\nneed aspect-oriented programming. With it, you don't have to create a new\nclass from `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIView`), ` but also can achieve the goal of intervening the pan\ngesture recognizer's work and this intervention can affect the subclasses\ninherited to `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIScrollView`), `.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Aspect-Oriented Programming Introduction`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Aspect-oriented programming probably is one of those terms which are\nexplained the most over-complicated in the programming world.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The most similar thing compared to aspect-oriented programming I think is\nplant grafting.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Plant grafting means to fix a shoot or twig to a slit of the trunk or\nstem of a living plant, such that the shoot or twig can receive sap from\nthe living plant and continue to grow up.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/95cf848fe1c4a14eec250b1a50c87fe2/5dfd1/plant-grafting.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/95cf848fe1c4a14eec250b1a50c87fe2/0cc25/plant-grafting.png\",\n        \"srcSet\": [\"/static/95cf848fe1c4a14eec250b1a50c87fe2/5116e/plant-grafting.png 178w\", \"/static/95cf848fe1c4a14eec250b1a50c87fe2/92f55/plant-grafting.png 356w\", \"/static/95cf848fe1c4a14eec250b1a50c87fe2/0cc25/plant-grafting.png 712w\", \"/static/95cf848fe1c4a14eec250b1a50c87fe2/7ae06/plant-grafting.png 1068w\", \"/static/95cf848fe1c4a14eec250b1a50c87fe2/eee47/plant-grafting.png 1424w\", \"/static/95cf848fe1c4a14eec250b1a50c87fe2/64e63/plant-grafting.png 1440w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/95cf848fe1c4a14eec250b1a50c87fe2/690c8/plant-grafting.webp\",\n        \"srcSet\": [\"/static/95cf848fe1c4a14eec250b1a50c87fe2/25c8a/plant-grafting.webp 178w\", \"/static/95cf848fe1c4a14eec250b1a50c87fe2/60698/plant-grafting.webp 356w\", \"/static/95cf848fe1c4a14eec250b1a50c87fe2/690c8/plant-grafting.webp 712w\", \"/static/95cf848fe1c4a14eec250b1a50c87fe2/d7e52/plant-grafting.webp 1068w\", \"/static/95cf848fe1c4a14eec250b1a50c87fe2/456ef/plant-grafting.webp 1424w\", \"/static/95cf848fe1c4a14eec250b1a50c87fe2/5dfd1/plant-grafting.webp 1440w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/95cf848fe1c4a14eec250b1a50c87fe2/5dfd1/plant-grafting.webp\",\n        \"alt\": \"Plant Grafting\",\n        \"title\": \"Plant Grafting\",\n        \"width\": 712,\n        \"height\": 506,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            Plant Grafting\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Aspect-oriented programming is quite like plant grafting.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/cad6b3de72647907e6febcd07075e415/5dfd1/plant-grafting-vs-aop.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/cad6b3de72647907e6febcd07075e415/0cc25/plant-grafting-vs-aop.png\",\n        \"srcSet\": [\"/static/cad6b3de72647907e6febcd07075e415/5116e/plant-grafting-vs-aop.png 178w\", \"/static/cad6b3de72647907e6febcd07075e415/92f55/plant-grafting-vs-aop.png 356w\", \"/static/cad6b3de72647907e6febcd07075e415/0cc25/plant-grafting-vs-aop.png 712w\", \"/static/cad6b3de72647907e6febcd07075e415/7ae06/plant-grafting-vs-aop.png 1068w\", \"/static/cad6b3de72647907e6febcd07075e415/eee47/plant-grafting-vs-aop.png 1424w\", \"/static/cad6b3de72647907e6febcd07075e415/64e63/plant-grafting-vs-aop.png 1440w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/cad6b3de72647907e6febcd07075e415/690c8/plant-grafting-vs-aop.webp\",\n        \"srcSet\": [\"/static/cad6b3de72647907e6febcd07075e415/25c8a/plant-grafting-vs-aop.webp 178w\", \"/static/cad6b3de72647907e6febcd07075e415/60698/plant-grafting-vs-aop.webp 356w\", \"/static/cad6b3de72647907e6febcd07075e415/690c8/plant-grafting-vs-aop.webp 712w\", \"/static/cad6b3de72647907e6febcd07075e415/d7e52/plant-grafting-vs-aop.webp 1068w\", \"/static/cad6b3de72647907e6febcd07075e415/456ef/plant-grafting-vs-aop.webp 1424w\", \"/static/cad6b3de72647907e6febcd07075e415/5dfd1/plant-grafting-vs-aop.webp 1440w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/cad6b3de72647907e6febcd07075e415/5dfd1/plant-grafting-vs-aop.webp\",\n        \"alt\": \"Plant Grafting v.s. AOP\",\n        \"title\": \"Plant Grafting v.s. AOP\",\n        \"width\": 712,\n        \"height\": 506,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            Plant Grafting v.s. AOP\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `As the above figure shown, aspect-oriented programming concerns about\nthree things:`), React.createElement(MDXTag, {\n      name: \"ul\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, `The added code`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, `The aspect`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, `The manipulated object`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `We can take the `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `added code`), ` in aspect-oriented programming as `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `twig`), `\nin plant grafting, the `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `aspect`), ` as the `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `slit`), ` and the\n`, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `manipulated object`), ` as the `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `living plant`), `. Then aspect-oriented\nprogramming is `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `to fix`), ` these three things together.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Existed Aspect-Oriented Programming in Objective-C and Swift`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `There is a misunderstanding about aspect-oriented programming in\nObjective-C: aspect-oriented programming is not officially supported by\nApple.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `No.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Key-Value Observation is just an ad-hoc aspect-oriented programming\nframework in Objective-C and is an official feature shipped by Apple. We\ncan plug Key-Value Observation in previous plant grafting model:`), React.createElement(MDXTag, {\n      name: \"ul\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `The property changes event triggers of a key-value observed object's\nare the twig (new code).`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `An observable property is the slit (aspect).`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `A key-value observed object is the living plant (manipulated object).`))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Thus we can know that Key-Value Observation is of aspect-oriented\nprogramming, but its \"aspect\" is \"ad-hoc\" and what Apple don't officially\nsupport is a \"general\" aspect support to aspect-oriented programming.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Aspect-oriented programming in Swift is complicated. With the legacy of\nObjective-C, Swift supports Key-Value Observation by default. But since\ndispatches of function calls can be potentially resolved at compile time\nand are written to the compiled products, and Key-Value Observation\ngenerates code at run-time, the compiled products may always not know how\nto call those run-time generated code and you need to markup your observed\nproperties with `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@objc`), ` attribute, which enforces the compiler to\ngenerate codes to resolve the dispatch of the function at run-time.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Like Objective-C, there is no \"general\" aspect support in aspect-oriented\nprogramming in Swift.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Well done. Apple made a good framework then we enjoy it and you still\ncannot be managed to intervene the pan gesture recognizer of\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIScrollView`), ` -- is that the story's end?`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Nope.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Implementing General Aspect Supported Aspect-Oriented Programming`), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `A Naïve Approach`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The simplest way to modify the behavior of a class instance in Objective-C\nwithout subclassing is method swizzling. There are a lot of materials\ntalked about doing method swizzling in Objective-C or Swift, thus I don't\nwant to repeat it here again. I want to talk about the disadvantages of\nthis approach.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Firstly, method swizzling are done to classes. If we swizzled\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIScrollView`), `, then all the instances of `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIScrollView`), ` and its\ndescendants get the same behavior.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Then, even we are doing aspect-oriented programming, we don't mean to\nabandon making `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `is-a`), ` assertions, which is the key step to draw the\nboundary of components' responsibilities and a corner stone of\nwhatever-oriented programming. Method swizzling is an anonymous approach\nof modification which bypasses \"making `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `is-a`), ` assertions\". This kind of\nmodification is likely to swing the foundation of software architecture\nand hard to spot and trace.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Moreover, since Swift doesn't support overload `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `class func load()`), ` method\nof Objective-C bridged classes, many posts suggest you to put the method\nswizzling code in `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `class func initialize()`), ` instead. For there is only one\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `class func initialize()`), ` overload would be called for a class in a module\nat app's launch time, then you have to put all the method swizzling code\nof a class in one file -- or you would not know which\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `class func initialize()`), ` is called at launch time on earth, it might turn\nout to be very tedious to manage the method swizzling code.`), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `A Sophisticated Approach`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `By giving a glimpse to the official supported aspect-oriented programming\nframework -- Key-Value Observation, we can spot that it totally don't\nhave the disadvantages I talked above. How did Apple achieve this?`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `In fact, Apple implemented this aspect-oriented programming technique with\na technique called is-a swizzling.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Is-a swizzling is quite simple, even reflect on the code -- set an\nobject's is-a pointer to another class'.`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-objectivec\"\n      }\n    }, `Foo * foo = [[Foo alloc] init];\nobject_setClass(foo, [Bar class]);\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `And Key-Value Observation is just to create a subclass which inherited to\nthe observed object's class, then set the observed object's is-a pointer\nto the is-a pointer of the newly created class. The whole progress can be\nillustrated in following code:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-objectivec\"\n      }\n    }, `@interface Foo: NSObject\n// ...\n@end\n\n@interface NSKVONotifying_Foo: Foo\n// ...\n@end\n\nNSKVONotifying_Foo * foo = [[NSKVONotifying_Foo alloc] init];\nobject_setClass(foo, [NSKVONotifying_Foo class]);\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Since Apple have handed out a sophisticated solution about an \"ad-hoc\"\naspect-oriented programming, creating a subclass of the class of an object\nand then setting its is-a pointer to the object's might work. But when\ndoing system design, the most important problem is: why may it work?`), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `An Analysis to KVO's design`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Open Swift Playground and typing following code:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\",\n        \"metastring\": \"version=4.2\",\n        \"version\": \"4.2\"\n      }\n    }, `import Cocoa\n\nclass Foo: NSObject {\n    @objc var intValue: Int = 0\n}\n\nclass Observer: NSObject { }\n\nlet foo = Foo()\n\nlet observer = Observer()\n\n// We need to use \\`object_getClass\\` to check the real is-a pointer.\n\nprint(NSStringFromClass(object_getClass(foo)!))\nprint(NSStringFromClass(object_getClass(observer)!))\n\nfoo.addObserver(observer, forKeyPath: \"intValue\", options: .new, context: nil)\n\nprint(NSStringFromClass(object_getClass(foo)!))\nprint(NSStringFromClass(object_getClass(observer)!))\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Then you can see the output:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-text\"\n      }\n    }, `__lldb_expr_2.Foo\n__lldb_expr_2.Observer\nNSKVONotifying___lldb_expr_2.Foo\n__lldb_expr_2.Observer\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `__lldb_expr_2`), ` is the module name generated by the Swift Playground and\nadded by the Swift compiler when bridging Swift class to Objective-C.\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `NSKVONotifying_`), ` is the guarding prefix added by KVO. `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Foo`), ` and\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Observer`), ` is the class name we used in source code.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `By such a glimpse to the internal of KVO, we can know that KVO creates\na new class for the observed object. But is it enough? I mean, is it\nenough that one subclass for observed objects of one class?`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Since KVO is a sophisticated framework, we can answer \"yes\" by intuition.\nBut if we do so, then we lost an opportunity to learn the reason why this\nis enough.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `In fact, since all the variants in observing an object's properties in KVO\nare only in the observer's event handler:\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `[NSObject -observeValueForKeyPath:ofObject:change:context:]`), `, on the\nother hand, the observed object is just about to sending events -- which\nis quite mechanical, the observed object side is dumbly fixed. This means\none subclass for observed objects of one class is totally enough --\nbecause those observed objects of the same class actually work the same\nway.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Replace the code in your Swift Playground with following code:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\",\n        \"metastring\": \"version=4.2\",\n        \"version\": \"4.2\"\n      }\n    }, `import Cocoa\n\nclass Foo: NSObject {\n    @objc var intValue: Int = 0\n}\n\nclass Observer: NSObject { }\n\nlet foo = Foo()\n\nlet observer = Observer()\n\nfunc dumpObjCClassMethods(class: AnyClass) {\n    let className = NSStringFromClass(\\`class\\`)\n\n    var methodCount: UInt32 = 0;\n    let methods = class_copyMethodList(\\`class\\`, &methodCount);\n\n    print(\"Found \\\\(methodCount) methods on \\\\(className)\");\n\n    for i in 0..<methodCount {\n        let method = methods![numericCast(i)]\n\n        let methodName = NSStringFromSelector(method_getName(method))\n        let encoding = String(cString: method_getTypeEncoding(method)!)\n\n        print(\"\\\\t\\\\(className) has method named '\\\\(methodName)' of encoding '\\\\(encoding)'\")\n    }\n\n    free(methods)\n}\n\nfoo.addObserver(observer, forKeyPath: \"intValue\", options: .new, context: nil)\n\ndumpObjCClassMethods(class: object_getClass(foo)!)\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Then you get the output:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-text\"\n      }\n    }, `Found 4 methods on NSKVONotifying___lldb_expr_1.Foo\n    NSKVONotifying___lldb_expr_1.Foo has method named 'setIntValue:' of encoding 'v24@0:8q16'\n    NSKVONotifying___lldb_expr_1.Foo has method named 'class' of encoding '#16@0:8'\n    NSKVONotifying___lldb_expr_1.Foo has method named 'dealloc' of encoding 'v16@0:8'\n    NSKVONotifying___lldb_expr_1.Foo has method named '_isKVOA' of encoding 'c16@0:8'\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `By dumping the method of the class that created by KVO, we can notice that\nthere were several methods overloaded by it. The purpose of overloading\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `setIntValue:`), ` is quite straight -- we told the framework to observe the\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `intValue`), ` property, thus it overloaded the method to add notification\ncodes; `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `class`), ` must be overloaded to return a fake is-a pointer which\npoints to the original class the object was; The purpose of overloading\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `dealloc`), ` probably is intended to release some garbage; The new method\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_isKVOA`), ` is like a method returns boolean value by Cocoa's naming\nconvention. We can add following code in our Swift Playground:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\",\n        \"metastring\": \"version=4.2\",\n        \"version\": \"4.2\"\n      }\n    }, `let isKVOA = foo.perform(NSSelectorFromString(\"_isKVOA\"))!.toOpaque()\n\nprint(\"isKVOA: \\\\(isKVOA)\")\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Then we get:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-text\"\n      }\n    }, `isKVOA: 0x0000000000000001\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Since the boolean true in Objective-C are practically stored as `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `1`), ` in\nmemory, thus we can ensure that `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_isKVOA`), ` is just a method returns\nboolean value. Obviously, we can infer that `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_isKVOA`), ` indicates whether\nthis class is a KVO generated class (Though we don't know what the\ntrailing `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `A`), ` extactly means to be).`), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Our System`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Our system is not quit different from KVO.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `First, our goal is to design a system offers \"general\" aspect support to\naspect-oriented programming, which means you can inject custom\nimplementation to any objects and any methods. This leads that creating\none class to umbrella all the changes done to the injected objects of one\nclass is no longer capable.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Second, we want a nominal approach instead of a non-nominal, or say\nanonymous approach to make such an injection. Giving something a name\nmakes us to draw the boundary of responsibilities of the thing, and the\nboundaries of responsibilities are the foundation of clean software\narchitecture.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Third, we want the system doesn't introduce any mechanisms that would\nresult to \"scare\" developers.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `By referring to the design of KVO, we can hand out the following design:`), React.createElement(MDXTag, {\n      name: \"ul\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `An object ( `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Foo * foo`), ` ) contains the methods to be injected into.`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `A protocol ( `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Aspect`), ` ) to represent the aspect which defines the\nmethods to be injected into (enforces the developer to give a name to\nthe aspect).`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `A class ( `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Bar`), ` ) nominally implements the aspect and offers\nimplementations of the methods to be injected with.`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `When an object was injected with custom implementations, the system\ncreates a subclass ( `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_ObjCGrafted_Foo_Aspect->Bar`), ` ) which identifies\neach other by taking all the existed injections and incoming injections\ninto consideration and sets the object's is-a pointer to the newly\ncreates subclass'.`))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/16eb4/mechanism-explained.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/0cc25/mechanism-explained.png\",\n        \"srcSet\": [\"/static/6c62c6053ee1ea1fd9cfd249e70bacec/5116e/mechanism-explained.png 178w\", \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/92f55/mechanism-explained.png 356w\", \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/0cc25/mechanism-explained.png 712w\", \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/7ae06/mechanism-explained.png 1068w\", \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/eee47/mechanism-explained.png 1424w\", \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/bf60c/mechanism-explained.png 1560w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/690c8/mechanism-explained.webp\",\n        \"srcSet\": [\"/static/6c62c6053ee1ea1fd9cfd249e70bacec/25c8a/mechanism-explained.webp 178w\", \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/60698/mechanism-explained.webp 356w\", \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/690c8/mechanism-explained.webp 712w\", \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/d7e52/mechanism-explained.webp 1068w\", \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/456ef/mechanism-explained.webp 1424w\", \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/16eb4/mechanism-explained.webp 1560w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/6c62c6053ee1ea1fd9cfd249e70bacec/16eb4/mechanism-explained.webp\",\n        \"alt\": \"Mechanism Explained\",\n        \"title\": \"Mechanism Explained\",\n        \"width\": 712,\n        \"height\": 571,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            Mechanism Explained\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `You may have spotted that the name of the class created by our system\ncontains characters \"->\" which is illegal in source code. But in\nObjective-C runtime environment, these characters are permitted to be a\npart of the class name. These characters build up a guaranteed fence\nbetween system generated classes and those user created classes in\nsource code.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The implementation is quite simple until you got touched with resolving\nprotocol hierarchy: which implementations should I take to inject with?`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Considering following codes:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-objectivec\"\n      }\n    }, `@protocol Foo<NSObject>\n- (void)bar;\n@end\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Since `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Foo`), ` inherited to `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `NSObject`), ` protocol, the declaration of method:\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `-isKindOfClass:`), ` is\b contained in the hierarchy. When we us this\nprotocol as an aspect, should we take the implementation of\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `-isKindOfClass:`), ` and inject it to the injected object?`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Obviously not.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Since the aspect is the \"proposal\" of the injection, and the class\noffers implementations to be injected with, I set a limitation here that\nthe system would only inject implementations which is implemented by the\nleaf level of the class offers implementations. This means methods like\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `-isKindOfClass:`), ` would not be injected when you don't offer a custom\nimplementation in the class offers custom implementations, and you still\ncan inject methods like it when you implement your custom version in the\nclass offers custom implementations.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Finally, there is the `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"p\",\n      props: {\n        \"href\": \"https://github.com/WeZZard/ObjCGraft\"\n      }\n    }, `repository`), ` and the API looks like below:`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/4846df2f2746b0651b59f9cbe07354ae/5dfd1/api-explained.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/4846df2f2746b0651b59f9cbe07354ae/0cc25/api-explained.png\",\n        \"srcSet\": [\"/static/4846df2f2746b0651b59f9cbe07354ae/5116e/api-explained.png 178w\", \"/static/4846df2f2746b0651b59f9cbe07354ae/92f55/api-explained.png 356w\", \"/static/4846df2f2746b0651b59f9cbe07354ae/0cc25/api-explained.png 712w\", \"/static/4846df2f2746b0651b59f9cbe07354ae/7ae06/api-explained.png 1068w\", \"/static/4846df2f2746b0651b59f9cbe07354ae/eee47/api-explained.png 1424w\", \"/static/4846df2f2746b0651b59f9cbe07354ae/64e63/api-explained.png 1440w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/4846df2f2746b0651b59f9cbe07354ae/690c8/api-explained.webp\",\n        \"srcSet\": [\"/static/4846df2f2746b0651b59f9cbe07354ae/25c8a/api-explained.webp 178w\", \"/static/4846df2f2746b0651b59f9cbe07354ae/60698/api-explained.webp 356w\", \"/static/4846df2f2746b0651b59f9cbe07354ae/690c8/api-explained.webp 712w\", \"/static/4846df2f2746b0651b59f9cbe07354ae/d7e52/api-explained.webp 1068w\", \"/static/4846df2f2746b0651b59f9cbe07354ae/456ef/api-explained.webp 1424w\", \"/static/4846df2f2746b0651b59f9cbe07354ae/5dfd1/api-explained.webp 1440w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/4846df2f2746b0651b59f9cbe07354ae/5dfd1/api-explained.webp\",\n        \"alt\": \"API Explained\",\n        \"title\": \"API Explained\",\n        \"width\": 712,\n        \"height\": 506,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            API Explained\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `And there is the example code to intervene the pan gesture recognizer\nof `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `UIScrollView`), `.`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-objectivec\",\n        \"metastring\": \"path=MyUIScrollViewAspect.h\",\n        \"path\": \"MyUIScrollViewAspect.h\"\n      }\n    }, `@protocol MyUIScrollViewAspect<NSObject>\n- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;\n@end\n`)), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-objectivec\",\n        \"metastring\": \"path=MyUIScrollView.h\",\n        \"path\": \"MyUIScrollView.h\"\n      }\n    }, `#import <UIKit/UIKit.h>\n@interface MyUIScrollView: UIScrollView<MyUIScrollViewAspect>\n@end\n`)), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-objectivec\",\n        \"metastring\": \"path=MyUIScrollView.m\",\n        \"path\": \"MyUIScrollView.m\"\n      }\n    }, `#import \"MyUIScrollView.h\"\n\n@implementation MyUIScrollView\n- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;\n{\n    // Do what you wanna do.\n    return [super gestureRecognizerShouldBegin: gestureRecognizer];\n}\n@end\n`)), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-objectivec\",\n        \"metastring\": \"path=MyViewController.m\",\n        \"path\": \"MyViewController.m\"\n      }\n    }, `// ...\nUIScrollView * scrollView = [UIScrollView alloc] init];\nobject_graftImplemenationOfProtocolFromClass(scrollView, @protocol(MyUIScrollViewAspect), [MyUIScrollView class]);\n// ...\n`)), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `A Sequel to the Framework`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `I designed this framework in 2017. I didn't have much experience about\ndesigning a framework which also contributes to easing the pain of\nbuilding software at that time. The thing I cared the most at that time\nwas drawing boundaries of responsibilities such that we can make a clean\nsoftware architecture. But the development of software is progressive.\nThis design may give an opportunity to a clean software architecture, but\nenforcing developers to give an aspect a name at the very beginning time\nslows down the progress of development.`), React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `Name that can be named is not universal and eternal Name.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `-- Lao Tsu`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `We give something a name for somewhat purpose. If the purpose changes,\nthe name changes as follow. For example, the category of the parts of a\npig with a butcher's perspective is different from those of a biologist's.\nIn the progress of software development, the purpose comes from how we\ndefine the questions and how we explain them, which varies as the\ndevelopment of the whole software developing progress. Thus a good\nframework which really contributes to easing the pain of building software\nshall have a portion of API makes use anonymous functions, or say closures\nin Swift and blocks in Objective-C, which can prevent us from naming\nsomething before we have sophisticated perspective upon it. But since this\nframework was designed in 2017 and I don't realize the things I mentioned\nabove, it doesn't support any anonymous functions.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `I need more research to make this framework to support anonymous\nfunctions. At least, at glance, the size of the reference of function in\nSwift is 2 words which that of C is 1. Plus, compile-time resolving is\ntroublesome. Obviously this needs enormous amount of work and currently I\ndon't have so much time. But it would come true in the future.`), React.createElement(MDXTag, {\n      name: \"hr\",\n      components: components\n    }), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"p\",\n      props: {\n        \"href\": \"https://github.com/WeZZard/ObjCGraft\"\n      }\n    }, `Repository`), ` mentioned in this post.`));\n  }\n\n}\nMDXContent.isMDXComponent = true;","scope":""},"headings":[{"value":"Case Study: Intervening UIScrollView Instances's Pan Gesture Recognizer","depth":2},{"value":"Aspect-Oriented Programming Introduction","depth":2},{"value":"Existed Aspect-Oriented Programming in Objective-C and Swift","depth":2},{"value":"Implementing General Aspect Supported Aspect-Oriented Programming","depth":2},{"value":"A Naïve Approach","depth":3},{"value":"A Sophisticated Approach","depth":3},{"value":"An Analysis to KVO's design","depth":3},{"value":"Our System","depth":3},{"value":"A Sequel to the Framework","depth":2}]}}},"earlierPostExcerpt":{"slug":"/post/2019/02/hello-world-9cf1","title":"Hello, World!","subtitle":"","createdTime":"2019-02-05T00:00:00.000Z","tags":[],"category":"Publication","file":{"childMdx":{"excerpt":"Hello, world! I haven't been writing blog posts for a long time. The reason why I had given\nup blogging is that currently there are no blog systems fulfill all my needs. I\ntried to get used to Medium. I love its reply system -- which guides people to\nwrite a new post instead of a simple comment…"}}},"laterPostExcerpt":{"slug":"/post/2019/03/an-introduction-to-gatsblog-5eca","title":"An Introduction to Gatsblog","subtitle":"A Blog Built with Gatsby.js","createdTime":"2019-03-02T00:00:00.000Z","tags":["Blog","Design","Programming","Gatsblog"],"category":"Showcase","file":{"childMdx":{"excerpt":"This post has been revisited with LLM technology to improve its English\nfluency. As mentioned in my Hello World post, no existing blog system fully meets my\nneeds, especially given my deep involvement with frontend technology. This led me to create my own solution. This post documents my journey…"}}}},"pageContext":{"postId":"6711bea1-42f1-543e-bb9c-8740e10314f0","earlierPostId":"ddd97bb5-2ed3-509f-95d6-6b52f87716c7","laterPostId":"ae21300f-a727-599f-a4f6-90375edebef3"}}