惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
I
InfoQ
H
Help Net Security
GbyAI
GbyAI
博客园 - 叶小钗
Recent Announcements
Recent Announcements
Engineering at Meta
Engineering at Meta
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
Y
Y Combinator Blog
L
LangChain Blog
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
F
Fortinet All Blogs
G
Google Developers Blog
Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
博客园 - Franky
D
Docker
Jina AI
Jina AI
罗磊的独立博客

Peter Steinberger

OpenClaw, OpenAI and the future | Peter Steinberger Shipping at Inference-Speed | Peter Steinberger The Signature Flicker | Peter Steinberger Just Talk To It - the no-bs Way of Agentic Engineering | Peter Steinberger Claude Code Anonymous | Peter Steinberger Live Coding Session: Building Arena | Peter Steinberger My Current AI Dev Workflow | Peter Steinberger Essential Reading for Agentic Engineers - August 2025 | Peter Steinberger Just One More Prompt | Peter Steinberger Poltergeist: The Ghost That Keeps Your Builds Fresh | Peter Steinberger Don't read this Startup Slop | Peter Steinberger Essential Reading for Agentic Engineers - July 2025 | Peter Steinberger Self-Hosting AI Models After Claude's Usage Limits | Peter Steinberger Logging Privacy Shenanigans | Peter Steinberger VibeTunnel's first AI-anniversary | Peter Steinberger Making AppleScript Work in macOS CLI Tools: The Undocumented Parts | Peter Steinberger Peekaboo 2.0 – Free the CLI from its MCP shackles | Peter Steinberger Command your Claude Code Army, Reloaded | Peter Steinberger Essential Reading for Agentic Engineers | Peter Steinberger Slot Machines for Programmers: How Peter Builds Apps 20x Faster with AI | Peter Steinberger My AI Workflow for Understanding Any Codebase | Peter Steinberger stats.store: Privacy-First Sparkle Analytics | Peter Steinberger Showing Settings from macOS Menu Bar Items: A 5-Hour Journey | Peter Steinberger VibeTunnel: Turn Any Browser into Your Mac's Terminal | Peter Steinberger Vibe Meter 2.0: Calculating Claude Code Usage with Token Counting | Peter Steinberger llm.codes: Make Apple Docs AI-Readable | Peter Steinberger Automatic Observation Tracking in UIKit and AppKit: The Feature Apple Forgot to Mention | Peter Steinberger Peekaboo MCP – lightning-fast macOS screenshots for AI agents | Peter Steinberger Migrating 700+ Tests to Swift Testing: A Real-World Experience | Peter Steinberger Commanding Your Claude Code Army | Peter Steinberger
UITableViewController designated initializer woes | Peter...
Peter Steinberger · 2015-04-15 · via Peter Steinberger

With Xcode 61, Apple added support for the NS_DESIGNATED_INITIALIZER flag, and also added this to various framework classes. This is likely a byproduct of Swift, where the initializer call order is much more strongly enforced. This goes as far as there’s a new convenience keyword to mark the separation of convenience vs designated initializers.

This is a good thing. It’s far too easy to break the initializer chain, even though Apple’s documentation on it is superb.

With iOS 8.3, Apple made a modification in UITableViewController that by now, every one using this class will have seen. initWithStyle: is now a designated initializer. And while throughout the beta period, this was the only designated one, the GM suddenly added both initWithNibName:bundle: and initWithCoder: to the list as well - making this class quite inconvenient to subclass.

Most of your subclasses will have their own designated initializer since they likely depend on some object at initialization time. If that’s the case, you generally want to prevent users from calling the wrong initializer, even if they are marked designated in the superclass.

A common idiom to do this is to declare them unavailable:

The above code belongs to the header and results in compile-time warnings. Since Objective-C is dynamic, this makes calling init harder, but does not prevent you from shooting yourself in the foot. To be complete, let’s also block this in the implementation:

Combining the two makes it really hard to create objects that are not correctly initialized. So of course I also tried to apply this pattern to UITableViewController… which results in an assert. Here’s the designated initializer chain I’d expect:

[PSPDFTableViewController initWithAnnotations:] -> [UITableViewController initWithStyle:] -> [UIViewController initWithNibName:bundle:] -> [NSObject init].

However, Apple didn’t really play by the rules in UITableViewController. It calls [super init] inside initWithStyle:. init is overridden in UIViewController to call initWithNibName:bundle: since this is the designated initializer per documentation, even though it’s not annotated with the NS_DESIGNATED_INITIALIZER decoration. This results in following call order:

[PSPDFTableViewController initWithAnnotations:] -> [UITableViewController initWithStyle:] -> [UIViewController init] -> [PSPDFTableViewController initWithNibName:bundle:] (which asserts!).

This is very unfortunate, and I assume it’s not easy to correct since there surely are apps out there who rely on this call order. We work around this by wrapping our implementation into a clang diagnostic block to ignore “-Wobjc-designated-initializers”, but it doesn’t prevent anyone from creating the controller with an invalid state. Maybe Apple fixes this conditionally in iOS 9. rdar://problem/20549233.

What other ways are there do deal with it? Did I miss something here?


1. To be correct, [Clang commit r196314](http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20131202/094628.html) landed in Xcode 5.1, so technically this already had support for designated initializers by using the `objc_designated_initializer` attribute directly.