Repository navigation
Keep @objc only where the Objective-C runtime needs it - #42
Merged
Merged
Conversation
When the host's types lost their LK prefixes and Objective-C names, the DEBUG-only end-to-end dump and UI snapshots in LookInside/DebugE2E/ became DebugE2EDump, DebugUISnapshots, DebugWindowImage and SnapshotNormalizer. check-host-release-clean.sh kept looking for LKDebugE2EDump, LKDebugUISnapshots, LKDebugWindowImage and LookinSnapshotNormalizer, names no binary contains any more, so that part of the check could no longer fail. It now looks for the new names. Scripts/test-check-host-release-clean.sh, which the build workflow now runs, keeps the check and the code in step. For every file in LookInside/DebugE2E/ it builds a throwaway app bundle that declares the file's types and expects the check to reject it, both with a symbol table and stripped; a bundle of ordinary host types must pass. Renaming a DebugE2E type without updating the check fails the test. Comments that still named the old types are updated as well.
The Swift host kept the @objc of the Objective-C host it replaced, but most of those members are now called only from Swift, which calls them directly rather than through the Objective-C runtime. The attribute only added Objective-C metadata and a thunk per member. This removes it from 405 declarations in 86 files: methods, initializers, properties, and explicit selectors written as @objc(name:). Nine of the properties were also dynamic although nothing observes them with KVO or animates them, and lose that too. Ten enums are no longer @objc, and AppDelegate and DanceScriptManager give up their Objective-C names, which nothing looks up. @objc stays where the Objective-C runtime has to find the member: #selector targets, properties observed with KVO or animated through animator(), methods AppKit calls by name such as the window's drag-and-drop methods, optional requirements of @objc protocols, the types those declarations use, and the three document classes Info.plist names. In a Debug build, 489 @objc thunks go away, each for one of these members or an override that inherited @objc from it, and none is added.
Five host members were reached through the Objective-C runtime from Swift code. The DEBUG UI snapshots read StaticViewController's dashboardController, DashboardViewController's scrollView and HierarchyView's searchTextFieldView with value(forKey:); the Dashboard sent updateAfterModifyingDisplayItem: to StaticAsyncUpdateManager with perform(_:with:); and DisplayItem's optionalAppropriateScreenshot read appropriateScreenshot with value(forKey:), because the Objective-C header the method used to be declared in promised a non-nil image. All five are now ordinary property reads and calls, so the members lose @objc. optionalAppropriateScreenshot goes: appropriateScreenshot() is a Swift method now, and its optional result already says it can be nil. In a Debug build, exactly these five @objc thunks go away.
Nothing in the host uses these any more; most were kept as Objective-C entry points for callers that no longer exist: - VersionComparer.compare(newest:user:), which only forwarded to compare(expectedVersion:realVersion:) - LiveDocumentController's completion-handler form of openLiveDocument(for:) - PreferenceManager's callStackType and the PreferredCallStackType enum - PrivateDiscriminatorStore.isFeatureEnabled - PrivateDiscriminatorDashboardPayload.displayClassName, and the className of the descriptor it was filled from - LaunchViewController's init(window:) and LaunchWindowController's init(), shorthands for autoEnterOnInitialReload: false In a Debug build, LaunchWindowController's -init and the ivars of the two removed stored properties leave the Objective-C metadata; nothing else there changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Swift host kept most of the
@objcof the Objective-C host it replaced. Swift code calls those members directly, so the attribute only added Objective-C metadata and a thunk per member. This removes 412 of the host's 630@objc, turns the five places that still reached a member by name into direct calls, and deletes the members left without callers. Nothing changes for users.The 218 that remain are there because the Objective-C runtime has to find the member:
#selectortargets: actions, notification observers,MessageAttributesubscribers,BaseControlandTipsViewclick actionsanimator()(@objc dynamic)AppWindow's drag-and-drop methodsoptionalrequirements of@objcprotocols, which Swift requires to be marked@objcApart from these, only the three document classes
Info.plistlists underNSDocumentClasskeep Objective-C names.The compiler enforces the first item and the last two. Remove
@objcfrom a KVO property or a drag-and-drop method and the app still builds; thenobserve(\.x)crashes,animator()stops animating, or a dropped file no longer opens.Commits
Each commit builds on its own.
check-host-release-clean.shstill looked for the DEBUG-only types inLookInside/DebugE2E/under the names they had before the rename, which no binary contains any more; it now uses their Swift names. The newScripts/test-check-host-release-clean.sh, run by the build workflow, fails when one of those types is renamed and the check is not.@objcfrom members only Swift uses: 405 declarations in 86 files, including thedynamicof nine properties nothing observes,@objcon ten enums, and the Objective-C names ofAppDelegateandDanceScriptManager.value(forKey:)reads in the DEBUG UI snapshots, aperform(_:with:)in the Dashboard, and theoptionalAppropriateScreenshotwrapper, which goes.@objcon two initializers that override@objcones and are inferred@objcanyway.Testing
xcodebuildDebug build of every commit, with no new warnings. A Release build of the last commit passesScripts/check-host-release-clean.sh --local-build.Scripts/test-*.shpass.@objcthunks in the binary (fromnm, demangled) and the method and ivar lists of every class, category and protocol. Commit 2 removes 489 thunks, each for a member it changes or an override that inherited@objcfrom one; commit 3 removes exactly its five; commit 4 changes nothing; commit 5 removes onlyLaunchWindowController's-initand the ivars of the two deleted stored properties. No commit adds anything.Not yet checked by hand in the running app:
.lookinfile on a window opens it.