15 KiB
APP-4154 Phase 2 — Other ObjC objects checklist
Every ownership-producing message send in a non-ARC .m file, plus every Rust-side msg_send![class!(X), alloc] retained allocation. Each batch agent fills in the trailing columns, applies the fix, and ticks the row. See TECH.md for the decision rule.
Reproducible greps
rg -n '\balloc\]|\bnew\]|\bcopy\]|\bmutableCopy\]' -g '*.m' -g '*.mm'
rg -n 'msg_send!\[class!\([A-Za-z_]+\), alloc\]' -g '*.rs'
Ignore (not leaks):
[super dealloc]matches (crates/warpui/src/platform/mac/objc/menus.m:25).app/DockTilePlugin/WarpDockTilePlugin.m— compiled with-fobjc-arc.- Definitions of trait-style alloc helpers (e.g.
unsafe fn alloc(...) -> id { msg_send![class!(NSAlert), alloc] }incrates/warpui/src/platform/mac/app.rs:46when it's a helper; audit the callers instead).
Row format
- [ ] path:line — function — disposition (released|autoreleased|leaked|stored|?) — thread-origin — hot/cold — strategy — action
Batch 2.A — sentry-objc
Files: app/src/platform/mac/objc/crash_reporting.m.
- app/src/platform/mac/objc/crash_reporting.m:21 —
setUser— leaked ([[SentryUser alloc] init]never released) — appkit-main (called viaset_optional_user_informationonAppContext) — cold (auth login/logout) — explicit-release — added[user release]after[SentrySDK setUser:user] - app/src/platform/mac/objc/crash_reporting.m:76 —
recordBreadcrumb— released (post-#560[crumb release]on line 82) — rust-thread (forward_breadcrumb, any Rust thread; caller wraps inNSAutoreleasePool) — hot — explicit-release — no-op (already correct)
Batch 2.B — app-objc-misc
Files: app/src/platform/mac/objc/{app_bundle.m, services.m}.
app_bundle.m has no alloc]/new]/copy]/mutableCopy] hits — confirmed via re-grep, N/A (no rows to file).
NB: the @autoreleasepool { ... } around this function body drains autoreleased temporaries but does NOT balance [[X alloc] init]'s +1 retain. The rows below are retained-and-leaked until the enclosing scope exits; they need autorelease-helper (swap to [NSMutableArray array] etc.) or explicit-release, not ambient.
- app/src/platform/mac/objc/services.m:30 —
forFilesFromPasteboard:performAction:— retained (+1 from alloc/init,@autoreleasepooldoes not drain) and leaked prior to fix — appkit-main (Services dispatch) — cold — autorelease-helper — replaced with[NSMutableArray array] - app/src/platform/mac/objc/services.m:35 —
forFilesFromPasteboard:performAction:— retained (+1 from alloc/init) and leaked prior to fix — appkit-main — cold — autorelease-helper — replaced with[NSMutableArray array] - app/src/platform/mac/objc/services.m:37 —
forFilesFromPasteboard:performAction:— retained (+1 from alloc/init; no empty-init convenience ctor) and leaked prior to fix — appkit-main — cold — autorelease-helper — wrapped withautorelease - app/src/platform/mac/objc/services.m:42 —
forFilesFromPasteboard:performAction:— retained (+1 from alloc/init) and leaked prior to fix — appkit-main — cold — autorelease-helper — replaced with[NSMutableArray array] - app/src/platform/mac/objc/services.m:58 —
warp_register_services_provider— retained (bare[WarpServicesProvider alloc]withoutinit) and leaked prior to fix;setServicesProvider:adds its own retain per Apple docs — appkit-main pre-event-loop (called from Rustapp_services::mac::init) — cold (one-shot) — explicit-release — addedinit, paired with[provider release]aftersetServicesProvider:
Batch 2.C — warpui-windowing-objc
Files: crates/warpui/src/platform/mac/objc/{app.m, host_view.m, window.m, window_blur.m, fullscreen_queue.m, keycode.m}. window_blur.m confirmed to have no alloc]/new]/copy]/mutableCopy] matches (CoreFoundation CFBundleCreate/CFStringCreateWithCString are already balanced by CFRelease). N/A.
- crates/warpui/src/platform/mac/objc/app.m:65 —
registerGlobalHotkey— leaked (setObject:forKey:retains, but alloc+init +1 was never balanced) — appkit-main — cold — autorelease-helper — addedautoreleaseso_hotKeysholds the only reference - crates/warpui/src/platform/mac/objc/app.m:194 —
-[WarpDelegate init]— stored (module-level_hotKeysheld for app lifetime; WarpDelegate is itself deliberately leaked singleton perget_warp_app) — appkit-main — cold — ambient — no-op, intentional singleton - crates/warpui/src/platform/mac/objc/app.m:488 —
get_warp_app— stored (comment on line 483 states the delegate is deliberately leaked; guarded bydispatch_once) — appkit-main — cold — ambient — no-op, intentional singleton - crates/warpui/src/platform/mac/objc/app.m:501 —
make_delegated_menu— autoreleased — appkit-main — cold — autorelease-helper — no-op - crates/warpui/src/platform/mac/objc/app.m:509 —
make_services_menu_item— leaked (NSApp.servicesMenusetter retains; alloc+init +1 was never balanced) — appkit-main — cold — autorelease-helper — addedautorelease - crates/warpui/src/platform/mac/objc/app.m:512 —
make_services_menu_item— leaked (returned from factory; caller storessubmenuwhich retains) — appkit-main — cold — autorelease-helper — addedautoreleaseso the factory matches the rest of the menu-factory conventions in this file - crates/warpui/src/platform/mac/objc/app.m:524 —
make_warp_custom_menu_item— autoreleased — appkit-main — cold — autorelease-helper — no-op - crates/warpui/src/platform/mac/objc/app.m:527 —
make_warp_custom_menu_item— autoreleased — appkit-main — cold — autorelease-helper — no-op - crates/warpui/src/platform/mac/objc/host_view.m:281 —
-[WarpHostView initWithFrame:...]— stored (markedTextivar, released indealloc) — appkit-main — cold — explicit-release — no-op - crates/warpui/src/platform/mac/objc/host_view.m:282 —
-[WarpHostView initWithFrame:...]— leaked (textToInsertivar was not released indealloc) — appkit-main — cold — explicit-release — added[textToInsert release]to-dealloc - crates/warpui/src/platform/mac/objc/host_view.m:423 —
-insertText:replacementRange:— released (explicit[characters release]at line 445) — appkit-event — hot — explicit-release — no-op - crates/warpui/src/platform/mac/objc/host_view.m:470 —
-setMarkedText:...— stored (markedTextivar; previous value released at line 468, final release indealloc) — appkit-event — hot — explicit-release — no-op - crates/warpui/src/platform/mac/objc/host_view.m:472 —
-setMarkedText:...— stored (same pattern as :470) — appkit-event — hot — explicit-release — no-op - crates/warpui/src/platform/mac/objc/window.m:37 —
-enqueueFullscreenTransition— stored (module-levelfullscreenManagerviadispatch_once, intentional singleton) — appkit-main — cold — ambient — no-op - crates/warpui/src/platform/mac/objc/window.m:499 —
+[WarpWindow createWithContentRect:...]— retained and returned per thecreatenaming convention (caller owns); RustWindow::openstores the resultingidasnative_windowand AppKit releases it viareleasedWhenClosed = YES— appkit-main — cold — ambient — no-op, documented ownership transfer - crates/warpui/src/platform/mac/objc/window.m:663 —
+[WarpPanel createWithContentRect:...]— same as :499 (ownership transferred to Rust caller) — appkit-main — cold — ambient — no-op - crates/warpui/src/platform/mac/objc/window.m:689 —
create_warp_nspanel— released (manually balanced by[pool release]at line 714/719 post-edit) — appkit-main — cold — local-pool — no-op - crates/warpui/src/platform/mac/objc/window.m:693 —
create_warp_nspanel— stored (module-levelwindowOrderForTestsviadispatch_once, intentional singleton for integration tests) — appkit-main — cold — ambient — no-op - crates/warpui/src/platform/mac/objc/window.m:703 —
create_warp_nspanel— autoreleased — appkit-main — cold — autorelease-helper — no-op - crates/warpui/src/platform/mac/objc/window.m:708 —
create_warp_nspanel— leaked (NSWindow.delegateis weak; the +1 retain count was never balanced so the delegate outlived every window open) — appkit-main — cold — stored — tied delegate lifetime to window viaobjc_setAssociatedObject+ released caller's +1 - crates/warpui/src/platform/mac/objc/window.m:721 —
create_warp_nswindow— released (manually balanced by[pool release]at line 746/753 post-edit) — appkit-main — cold — local-pool — no-op - crates/warpui/src/platform/mac/objc/window.m:725 —
create_warp_nswindow— stored (same as :693) — appkit-main — cold — ambient — no-op - crates/warpui/src/platform/mac/objc/window.m:735 —
create_warp_nswindow— autoreleased — appkit-main — cold — autorelease-helper — no-op - crates/warpui/src/platform/mac/objc/window.m:740 —
create_warp_nswindow— leaked (same root cause as :708) — appkit-main — cold — stored — fixed alongside :708 withobjc_setAssociatedObject - crates/warpui/src/platform/mac/objc/fullscreen_queue.m:17 —
-[FullscreenWindowManager init]— stored (ivar onfullscreenManagersingleton which is itself intentionally leaked for app lifetime) — appkit-main — cold — ambient — no-op - crates/warpui/src/platform/mac/objc/keycode.m:163 —
charToKeyCodes— stored (module-levelkeycodeDictcache, intentional singleton built lazily on first call) — rust-thread? — cold — ambient — no-op, singleton cache - crates/warpui/src/platform/mac/objc/keycode.m:193 —
charToKeyCodes— leaked (setObject:forKey:retains; alloc+init +1 was never balanced) — rust-thread? — cold — autorelease-helper — addedautorelease - crates/warpui/src/platform/mac/objc/keycode.m:201 —
charToKeyCodes— leaked (same pattern as :193) — rust-thread? — cold — autorelease-helper — addedautorelease
Batch 2.D — warpui-chrome-objc
Files: crates/warpui/src/platform/mac/objc/{alert.m, menus.m, notifications/notifications.m, reachability.m, hotkey.m}. alert.m, menus.m (beyond [super dealloc]), and hotkey.m currently have no alloc] matches; agent confirms.
Confirmed via rg -n 'alloc\]|\bnew\]|\bcopy\]|\bmutableCopy\]' on each file in the working tree: alert.m, hotkey.m → no matches (N/A). menus.m → only [super dealloc] at line 25 (N/A).
- crates/warpui/src/platform/mac/objc/notifications/notifications.m:55 —
sendNotificationWithErrorHandlercompletion block — leaked (alloc/initUNMutableNotificationContentnever released) — gcd-block (UNUserNotificationCenter completion handler) — cold (per user-triggered notification) — autorelease-helper — added inlineautoreleaseon the alloc/init expression - crates/warpui/src/platform/mac/objc/reachability.m:93 —
+reachabilityWithHostname:— autoreleased — appkit-main (viawarp_app_will_finish_launching→setReachabilityListener) — cold (once per app lifetime) — autorelease-helper — addedautoreleaseso the factory matches Cocoa naming conventions; caller inapp.m:394nowretains and-[WarpDelegate dealloc]callsstopNotifier(to break thereachabilityObject = selfretain cycle set up by-startNotifier) followed byrelease. - crates/warpui/src/platform/mac/objc/reachability.m:105 —
+reachabilityWithAddress:— autoreleased — n/a (dead path today; only reached viareachabilityForInternetConnection/reachabilityForLocalWiFi/reachabilityWithURL, none of which are called in the current tree) — cold — autorelease-helper — addedautoreleasealongside :93 for consistency; no caller updates required because the path is unused today.
Batch 2.E — rust-msg-send-alloc
Rust-side msg_send![class!(X), alloc] sites that retain without autoreleasing. These require explicit balance or switching to an autoreleased helper.
crates/warpui_extras/src/user_preferences/user_defaults.rs:39 is adjacent to NSString lines audited by batch 1.D; to avoid merge conflicts it's owned by batch 1.D in nsstring_checklist.md, not this file.
- crates/warpui/src/platform/mac/app.rs:46 —
NSAlert::alloctrait impl — autoreleased (by caller) — appkit-main — cold — autorelease-helper — no-op: caller at :80create_native_platform_modalwraps the chain inNSAlert::autorelease(NSAlert::init(NSAlert::alloc(nil))), and the caller's callers (show_native_platform_modalindelegate.rs:375) run on the AppKit main thread where an ambient pool exists - crates/warpui/src/platform/mac/app.rs:187 —
App::run— retained (chained intoinitWithBytes_length_) — appkit-main — cold — ambient — no-op:App::runis a one-shot called frommain;NSAutoreleasePool::new(nil)at :178 spans the entire NSApp run loop and drains at :210 on app shutdown. The icon data is consumed synchronously by theNSImageinit at :192, and the resulting image is retained byNSAppviasetApplicationIconImage:at :206. Any residual retain is reclaimed at process exit. - crates/warpui/src/platform/mac/app.rs:192 —
App::run— retained (chained intoinitWithData_) — appkit-main — cold — ambient — no-op: same scope as :187. The produced image is handed off toNSAppviasetApplicationIconImage:(NSApp retains) at :206, and the outer pool at :178 covers the call; one-shot at startup, reclaimed on process exit. - crates/warpui/src/platform/mac/clipboard.rs:68 —
<impl Clipboard for Clipboard>::write— leaked (chainedalloc].initWithBytes_length_never balanced; pasteboard retains its own copy) — appkit-main — cold (user-initiated copy action, not a tight loop) — explicit-release — addedmsg_send![data, release]aftersetData:forType:to balance the+1from[NSData alloc]; pasteboard retain keeps the data alive for consumers - app/src/appearance.rs:234 —
AppearanceManager::set_app_icon— leaked (chainedalloc].initWithContentsOfFile:never balanced) — mixed (appkit-main from settings UI +ctx.spawncontinuation after autoupdate + app init inlib.rs:1204) — cold (fires on icon change, app start, after updates) — explicit-release — addedmsg_send![image, release]after the finalnoteFileSystemChanged:;setApplicationIconImage:andsetIcon:forFile:options:both retain the image, andinitWithContentsOfFile:releases theallocon failure, so the nil-check early return needs no additional release