Curtis Love

Curtis Herbert, Tough Love: Instead of looking inwards at a lack of success I think we would be better served looking outside our community. If we look externally we’ll see that the App Store isn’t full of doom-and-gloom bad for indies, but rather markets at large are stacked against indies. Absolutely right. I’d add, though, that each market has a shape, and the shape of the iOS App Store is in Apple’s control. They can’t control the behavior of people, but the shape of the market has an impact. I’d also add that a high volume of high-quality, interesting apps is good for selling iPhones and iPads. Are there things Apple could do that would make the iOS App Store better for indies, so that we’re not rejecting iOS app ideas out-of-hand? I think so. There’s no silver bullet, but there are numerous good ideas that, taken together, could make a significant difference. It’s still going to be tough for indies — there’s no way out of having to design well, work hard, and market effectively, and we wouldn’t want a way out; we like it tough — but every inch of lowered risk and every dollar of greater reward makes a difference.

Posted by on 1 July 2015 | 11:43 am

So Much Love

Allen Pike, The Supply-side Blues: However, when expressing frustration with the current economics of the App Store, we need to consider the effect of this mass supply of enthusiastic, creative developers. As it gets ever easier to write apps, and we’re more able to express our creativity by building apps, the market suffers more from the economic problems of other creative fields.

Posted by on 1 July 2015 | 10:57 am


At the Cyclops the other night I was talking with fellow Mac and iOS developers. One person mentioned that a friend had acquired an iOS game — a good game that’s less popular than it deserves, that maybe just needs some marketing. Person: “So here’s the question. Would my friend’s iOS app be successful if…” Everyone else at the table: “No!” We didn’t wait for the “if” clause, because there’s nothing that could be in it that would matter. That’s not to say that there aren’t successful iOS apps. Of course there are. I know people who work on them. I work with people who work on them. But the odds are so very long. Do we still talk about new apps and recommend apps to people? Hardly, these days. * * * Well, that’s freaking dark, and I guess I did say it out loud. Hello despair: …there’s nothing that could be in it that would matter. Okay. I feel responsible for letting you out of this post a bit more nicely. Despair isn’t my style. * * * If I estimate the number of iOS apps in the App Store, and get the difference between the estimate and the actual number, that difference will be larger than the number of successful apps. (I define successful as a good-faith “makes enough of a profit to make it worth continuing to work on the app.” Most apps fail to make a profit at all, of course.) I haven’t done an actual study. But do any developers doubt that I’m right? And when developers think this way, they take their app ideas and toss ’em aside. “Hey, you know what, this idea would be really great for iPad! Darn.” “This would be perfect for iPhone! Oh well.” Shrug. Whatareyagonnado? * * * Yes, there are strategies for making a living, and nobody’s entitled to anything. But it’s also true that the economics of a thing may be generally favorable or generally unfavorable — and the iOS App Store is, to understate the case, generally unfavorable. Indies don’t have a fighting chance. The platform is awesome. We love writing iOS apps. It’s fun and massively rewarding in every way except monetarily. As a craft — as a budding art form, perhaps — it’s juicy. * * * You might think that development needs to get easier in order to make writing apps economically viable. The problem is that we’ve seen what happens when development gets easier — we get a million apps on the iOS App Store. The easier development gets, the more apps we see. And, the easier development gets, the more is expected of the apps you write, and the less people will pay. You probably have to do syncing. You need a companion Apple Watch app. And so on. I kind of want to say that development needs to get harder — but what I really mean is that we need to solve harder problems in our app. Think of the difficulty level in things like Capo — do something actually very difficult like that, create a great UI and market the app well, and you may have a success. The problem, of course, is that you’re taking a big risk. Your odds may be better when you’re solving a truly difficult problem — but the investment in time is bigger. And that’s not a general solution to the economic problems of developing iOS apps. I don’t have one. Maybe there isn’t one. (Well, there’s Mac apps. Want a business? Write Mac apps. But that’s a closely-guarded secret, and I promised not to tell anyone. You didn’t hear it from me.) * * * This is the age of writing iOS apps for love. Well, that’s not true for everybody. Well-established and awesome companies such as Omni, Panic, Flexibits, AgileBits, Tapbots, and The Iconfactory have a business writing iOS apps. (They do it for love, but not just for love.) Companies like Black Pixel make money by writing apps for other companies that have money. And big companies and funded companies don’t actually have to make money from their iOS apps. They have other goals. (I don’t pretend to understand the economics of funded companies.) You the indie developer could become the next Flexibits. Could. But almost certainly not. Okay — not. What’s more likely is that you’ll find yourself working on a Mobile Experience for a Big National Brand(tm) and doing the apps you want to write in your spare time. If there’s a way out of despair, it’s in changing our expectations. Write the apps you want to write in your free time and out of love for the platform and for those specific apps. Take risks. Make those apps interesting and different. Don’t play it safe. If you’re not expecting money, you have nothing to lose. Could the do-it-for-love era — with the creative freedom that that brings — bring us back to the days when we downloaded apps that weren’t from Facebook and Starbucks and Funded Company X, and we told our friends about our exciting finds? I hope. I have hope.

Posted by on 30 June 2015 | 12:02 pm

Swift question: Enum vs. Struct for Variants

In a previous post I mentioned using structs plus a protocol to implement a variant type. There’s a Value protocol and a number of different structs that conform to that protocol. But Andy Matuschak’s comment about using an enum instead keeps coming to mind. And then there’s this note in the pre-release Swift book: Alternatively, enumeration members can specify associated values of any type to be stored along with each different member value, much as unions or variants do in other languages. So let’s imagine a variant that can represent a bunch of different data types and that has logic for arithmetic operations and for coercions. enum Value {   case variantBool(Bool)   case variantInt(Int)   case variantString(String)   etc. — for doubles, dates, data, collections, and so on } (Forgive the “variant” prefix in this example — it’s there so I’m not writing case Bool(Bool) and so on.) Now let’s say we have a bunch of logic. func canAddValue(value: Value) -> Bool func valueByAddingValue​(value: Value) -> Value And so on for subtracting, multiplying, and dividing. (Example: variantStrings can add and subtract other variantStrings and things that can be coerced to variantStrings, but they can’t multiply or divide. variantData can’t do any arithmetic at all. Etc.) And then add logic for coercions: func canCoerceToType​(type: Value) -> Bool func valueByCoercingToType​(type: Value) -> Value (This is a little weird because a Value is a type — variantBool, variantInt, etc. — as well as data.) There’s a whole ton of logic there: a variantDate can be coerced to a variantDouble but not to a variantArray, etc. Unless I’m missing something — which is highly likely, as I’m just barely starting — I’ve got a whole ton of switch statement to write. And those switch statements have inner switch statements. (Conceptually, that is. Of course I would break things out into separate functions, as in func variantBool​CanCoerceToType​(type: Value) -> Bool and so on.) That seems a lot to me like writing C code with tagged unions. Which is not necessarily a bad thing — I grew up on C and and still love programming in C (though I don’t get much chance to do it these days). My original idea — a Value protocol plus a bunch of structs conforming to Value, one for each type — is something an Objective-C developer who’s new to Swift would come up with. I realize it’s still early to ask about idiomatic Swift and best practices, but I’m asking anyway. What would you do?

Posted by on 23 June 2015 | 9:33 pm

Varieties of News Readers

I think — provisionally — that there are three types of news readers. (Am I missing any?) 1. Casual Newspaper This category includes Flipboard, Zite (sadly defunct), the upcoming Apple News, and others. These tend to have the richest user interfaces of all news readers, with lots of pictures, animations, and interesting layouts. Typically you pick some categories that interest you and perhaps some sites. You may also add RSS feeds and you might have it pull links from your Twitter and Facebook feeds. These tend to have significant server backends that not only read various feeds and sites but also assemble (via algorithms and curation) a set of articles personalized for each user. These are casual because, as with an actual newspaper, there’s no expectation that you’ll read everything. These tend not to have unread counts, for instance. 2. Productivity App This category includes apps like Reeder, NetNewsWire, Google Reader (now gone), Feedly, Fever, and others. Their user interface often resembles a Usenet reader or email app. These apps often have things like unread counts and power-user features such as extensive keyboard shortcuts. These tend to be RSS readers specifically, though not necessarily entirely so. They don’t always do anything about relevance or personalization — personalization is entirely in the hands of the user, who picks which feeds to read. Some do include relevance features, but in general these apps are for people who want the control in their own hands, who don’t trust algorithms or curators, who don’t want to miss something that might be important. There are two subcategories of productivity apps: browser-based server apps and native apps. Interestingly, the native apps often provide syncing by connecting to a server app (which may be made by a developer who’s not the same as the native-app developer). 3. River of News These are reverse-chronological streams with optional titles and a short amount of text — often just a summary or excerpt of the linked-to story. (See Dave Winer on What is a River of News aggregator?) These are also somewhat casual in that there are generally no unread counts and there’s no pressure to read everything. You read by scrolling, and you scroll as far as you want to. There are two subcategories: RSS (or RSS mostly) and social network feeds. Twitter and Facebook could both be considered news rivers. (The RSS variety came first by many years, of course.) Rivers sometimes have relevance algorithms behind them — as with Facebook, for instance — and sometimes not. They may be stand-alone, without any form of syncing, or they might have giant server back-ends — or something in between.

Posted by on 23 June 2015 | 3:26 pm

Swift Protocols Question

I’m still very much a Swift newbie. The following example is contrived, but it accurately depicts the problem I’m trying to solve. I have a protocol: protocol Value: Equatable A number of different structs conform to this protocol. Some of those structs also conform to this protocol: protocol Smashable {   func valueBySmashing​OtherValue​(value: Value) -> Value } My intent is absolutely clear — valueBySmashingOtherValue must return an object that conforms to the Value protocol. However, I get this error: Protocol 'Value' can only be used as a generic constraint because it has Self or associated type requirements. Okay. So I revise the Smashable protocol like this: protocol Smashable {   func valueBySmashing​OtherValue​<T>(value: T) -> T } That compiles. Cool. So in a struct named Foo I add this: func valueBySmashing​OtherValue​<T>(value: T) -> T {   return Bar() } That’s right — Foo’s ​valueBy​Smashing​OtherValue returns a Bar. (Yes, this is contrived, but it distills the more-complex real-world code, which makes sense and is absolutely the right thing to do.) Both conform to Value. But I get this error on the return Bar() line: 'Bar' is not convertible to 'T'. At this point I don’t know what to do. Hence this blog post. Objective-C version I approach Swift exactly like an Objective-C coder — because I’ve been writing Objective-C for almost 15 years. Here’s the Objective-C version: @protocol Value<NSObject> stuff @end @protocol Smashable<NSObject> - (id<Value>)valueBy​SmashingOtherValue:​(id<Value>)​otherValue; @end Foo method (Foo and Bar both conform to Value): - (id<Value>)valueBy​SmashingOtherValue:​(id<Value>)​otherValue {   return [[Bar alloc] init]; } One possibility I’m still thinking in Objective-C. It’s entirely likely that there’s a Swift-like design that hasn’t occurred to me. But what is it? One simple possibility: don’t use protocols at all. Make a Value struct that does everything the various Value-conforming structs currently do. The Value struct would be littered with switch statements, which is ugly (and is usually a sign of poor design), but it would work. This doesn’t seem Swift-like, though, given the importance of protocols to Swift. And I can’t make myself do it. There must be a better option. What I don’t want to do is complain, a la Nabokov, that this new language can’t match the suppleness of my native language. I’d rather assume it’s just that I haven’t learned this new language well enough. P.S. I’ll happily link to your blog post if you write up a solution. Update 10:30 am Monday June 22: Answers There are a bunch of replies on Twitter. The essence of the best answers was this: Value should not be Equatable — the individual structs should be Equatable. Brent Royal-Gordon: Thinking more, the problem is Equatable. Remove or abstract that conformance from Value and everything will work right. For more details, see David Owens II’s blog post: …there is a way out of this if your situation allows for it: don’t conform your protocol to Equatable, instead, conform your types to it. And Llamagraphics’s blog post: The error message says Protocol ‘Value’ can only be used as a generic constraint because it has Self or associated type requirements. This is a little misleading, because it implies that valueBySmashingOtherValue needs to be rewritten as a generic function, but that actually just pushes the problem down to the adopters of the Value protocol. The real fix is to move the use of the Equatable protocol from the Value protocol to the individual struct declarations… And see Andy Matuschak’s gist — which makes an interesting point that I had briefly considered and then dropped: One note before we start: if the inhabitants of Value are a closed set, then making Value an enum is going to be a clearer model than using a protocol like this. I'm assuming you need to be able to retroactively add new members of Value. In my case, the inhabitants of Value are a closed set. There are about a dozen. What concerned me, though, is that I’d be creating a monster enum with a whole bunch of switch statements. But perhaps that’s not true? I don’t know Swift well enough to think it out in advance — I’d have to try it and see. (Actually, I may be misunderstanding Andy. There are a dozen Value types — but the values are unbounded. Perhaps not a great case for an enum.) Ramble In the end, I’m still tempted to say the Objective-C version was simpler. And it is, and not just because I’m more familiar with Objective-C. But it’s important to note that it’s not apples-to-apples. In Objective-C I’m creating classes instead of structs, and there’s no support for the == operator. But I will say this: Objective-C, because it’s less strict with types, is closer to a scripting language than Swift is. I know that that could be controversial, and seems absurd when you consider that Objective-C is a superset of C, which is pretty darn far from a scripting language. But Objective-C as-we-mostly-write-it doesn’t include much straight C code. That’s not a value judgment but a characterization. There is a place for strict, less-strict, and not-strict-at-all languages — they all have their uses. But when I imagined Apple’s next-generation language, I imagined a higher-level and less strict language — one that made it easier to get started as a developer, one that got rid of a bunch of the housekeeping we have to do as Objective-C developers. Though Swift does get rid of a bunch of housekeeping — we can use type inference much of the time, we don’t have to create .h files, etc. — it adds its own housekeeping mandated by a stricter type system (and optionals). When I think about how much of our apps is user interface code — which is often rather boring to write and is just stuff like setting a label, animating a property, pushing a view controller, and so on — I wonder why we’re not using an actual scripting language. It wouldn’t have to be for all of a given app — not for the performance-sensitive parts — but it would be great for all the stuff that’s just pushing user interface APIs around.

Posted by on 21 June 2015 | 12:55 pm

More About http Deprecation

Dave Winer writes about http deprecation in The People’s Browser. And I’ve thought more about it in the context of writing Mac and iOS apps. Let’s consider a few apps I’ve worked on in my career: NetNewsWire: an RSS reader that connects to any site with an RSS feed, no matter how that feed is served (http or https). MarsEdit: a blog editor that connects to any blog with an external API, no matter how that API is served (http or https). Glassboard: a private group messaging system. Of these, only Glassboard would fit in an https-only world. Since we controlled the server, and since privacy and security were hugely important, requiring https would be no problem. (And of course we did use https.) The problem is the other two apps. They all rely on the open web rather than servers controlled by the app writer. And it would be unacceptable to limit those apps to https only. Let’s also consider my two secret-project Mac apps. Both of them need http access — they’re not limited to servers that I (or some corporation) control. Since neither app will be sandboxed, I’ll be able to do this without Apple’s approval. My concern, of course, is that this situation won’t last. (It already means that there couldn’t be iOS versions of my secret-project apps — at least not without Apple granting an exception, which may be temporary.) I’m totally on board with defeating the ability of the NSA and your internet provider and everybody else from snooping. I hate this snooping business — it’s anti-American and it makes me sick to my stomach for the future. But I also know that the web isn’t going to switch to https quickly or completely. It’s expensive. To cut off http is to cut off the arms of the body of free speech.

Posted by on 15 June 2015 | 2:00 pm

Secret Projects Diary #1: Post-WWDC Notes

Note: This series — which will probably last a long time — is my attempt at writing about things without actually announcing what they are. I’ve decided I can eat this cake and still have it. The point is not to tease — though I realize that that’s a side effect, and I apologize in advance. (It’s not going to stop me from saving actual announcements until the software is ready, and it’s not going to stop me from writing in the meantime. Because writing helps me think, and it’s fun.) Swift I started working on my apps a few months ago, and there was no question at the time that I should use Objective-C. But now with Swift 2 I wonder if it’s time to switch. The new Swift goes a long way toward curing angle-bracket blindness. But, more importantly, now we know what Swift will be once it grows up (and it’s growing up fast) — and that thing, a protocol-centered language, is a thing I want. (The most important session of this year’s WWDC was Protocol-Oriented Programming in Swift. It’s a peek into how we’re going to be writing software for the next decade and more. For the rest of my career.) I haven’t written much UI code yet. Almost everything so far has been data transformations — isolatable things that run outside the main thread, things that could benefit from Swift structs and enums rather than the collection of classes that I’m currently using. Objective-C is a living language, but Swift is the safer bet for the long term. And I want my apps to last a very long time. I’m torn between wanting to make forward progress and wanting to port the code so far. I haven’t decided yet. I might do these things concurrently. OS X 10.11 and Auto Layout My apps will both require 10.11. That was never in doubt. One of the interesting changes is that AppKit (with split views, particularly) has more of a concept of a sidebars and content lists. And there are some new behaviors, such as automatically hiding a sidebar and showing it as an overlay, that we get if adopt the new APIs. At least one of my apps (and possibly both; undecided for now) will have a sidebar. But I wasn’t planning on using Auto Layout because I’ve had problems with performance, bugs (in NSToolbar), debugging, and with actually getting things to work the way I want. (I have not been able to replicate Mail’s splitview handling using NSSplitViewController, for example, but I can replicate it if I go the old-fashioned route.) Auto Layout solves a problem I don’t have. I’ve been writing manual layout code for so long that I barely even have to think about it. It’s easy. While I understand the benefits of declaring (as opposed to coding) layout, those benefits disappear when things go wrong and when I can’t do the thing I want to do. But this leads to a dilemma. Doing things the old-fashioned way means manually writing sidebars-that-overlay (and so on) and nailing the behavior perfectly and revising it every time the behavior changes. If I use Auto Layout instead, I get the behavior, and any changes to that behavior — but I also get an unknown set (of unknown size) of struggles and frustrations. If it’s a tie, then the winner is the future-proof answer. Which is Auto Layout. NSStackView Stack views in 10.10 are slow. (I can point to multiple performance issues in shipping apps that are a result of stack views.) Word on the street is that they’re much-improved in 10.11 — which is great. If that’s true, then I want to use them. There are lots of cases where a stack view is the best answer to a layout problem, and so I suspect there will be plenty of stack views in my apps. (As long as they truly are faster now. I haven’t checked yet.) http deprecation This one worries me a little, and I need to find out more. Since neither of my apps will be sandboxed, it may not be an issue. But it’s a larger issue in the industry and is bound to have an impact on what I do sooner or later. What upsets me about this issue in general is that it’s anti-democratic: it can make writing for the web more expensive and difficult for individuals. As a writer, reader, and open web partisan I dislike everything that shifts power away from people and toward entities with greater resources. What you end up with is corporate speech rather than the voices we know and love and need to hear. This is a complex situation, though. I strongly believe in the right to privacy, and that encryption should be used much more widely than it is today, and that no organizations, official or otherwise, should have back doors. Well. Anyway. More research and thought required on this one.

Posted by on 14 June 2015 | 3:37 pm

How Not to Crash Series Finished

All done. (At least I think so — I might think of more things, I suppose.) There’s a new page that links to all the posts. There’s a link to it at the bottom of every page on this site.

Posted by on 10 June 2015 | 6:20 pm

How Not to Crash #9: Mindset

You know the old line about not writing code that’s as clever as you are, because it will take someone even smarter than you to debug it? I used to think that means I should write code that’s about 80% as clever as I am. Save a little bit for debugging. But over the years I’ve come to think that I should write code that’s about 10% as clever as I am. And I’ve come to believe that true cleverness is in making code so clear and obvious that it looks like nothing at all. And that’s why I have rules like do everything on the main thread except for perfectly isolatable things and avoid unsafe_unretained always and so on. This means I don’t get bonus points for being a code magician. I don’t pull rabbits out of hats and I certainly don’t walk tightropes. I won’t even look at tightropes. I do difficult things as needed, but the goal even with the difficult things is to write the simplest and most-readable code that I can. If, in the end, the code looks easy — unimpressive, even, as if a middle-school kid could have written it — then good. In the small, this means that methods tend to be small and focused with little nesting. In the large, architecture and naming is iterated-over until it feels inevitable, as if no thought went into it because it all must have been obvious. It means not getting too abstract. Explicitness is obviousness. But it also means not getting too non-general, either — there are times when two or three things are really the same thing, and they can be generalized without harming maintainability. (And there are times when they can’t.) I avoid tight coupling and large structures — except for when the best solution really is for x to know about y. And I keep learning and getting better. Time The thing that separates programming from painting, writing, architecture, and composing music is that there is no finished product. There are released versions, yes, but there’s no finishing, there’s only abandoning. Code exists in time, and maybe across many people — and you don’t even know how long or who. This should never be out of your mind. Cape, mask When I was younger I wanted to be a code magician — or, really, a hero. But I learned that actual software quality is more important than what I imagine other people think of me. And, more: quality is a reward that’s almost spiritual. It’s an act of devotion, both selfish and unselfish, to something more important than ego. Selfish because the process of striving for quality makes you a better person. And unselfish because better code and better software is better for other people. And the first thing other people ask of your software is that, if they launch it, it stays launched. Any programmer who can’t bring themselves to care about that — or who rationalizes away crashing as a fact of life these days — isn’t taking this great fun we are privileged to have seriously enough.

Posted by on 10 June 2015 | 6:05 pm

How Not to Crash #8: Infrastructure

Even if you think your app is crash-free, you need to collect crash logs — because there’s no such thing as crash-free: it can only be free of known crashing bugs. There are a few different services for this, and the ones I’ve tried are pretty good, so I’m not going to make a specific recommendation. But there are a few things it should do: Crash logs should be collected without a user having to find them and send them to you. It should be automatic-ish (users should probably be prompted, if on OS X; on iOS nobody seems to expect a prompt). There should be a way to group crash logs, and you should get a total for each group, so you know which ones are frequent and which aren’t. You should be able to mark a group as resolved. It’s not enough, of course, just to collect crash logs. You should look at them regularly. (I look at crash logs every morning.) Bug tracker Have one. For my personal projects I use a combination of Lighthouse, OmniOutliner, and pen-and-paper — but you should use whatever works for you, as long as your crashes get into your bug tracker and don’t get lost. (Lighthouse is a good bug tracker. For mapping out big new features or entire apps I like OmniOutliner, where I can build a tree of things-to-do. For short-term things — for the 10 steps needed to complete a single task — I like pen and paper, since it’s tiring to rely on short-term memory, since pen and paper doesn’t disturb the on-screen context.) Errors and warnings Xcode by default doesn’t turn on enough errors and warnings. I strongly recommend Peter Hosey’s set. The point is to remove doubt from your code. I go a step further, which I also recommend: I turn on treat warnings as errors. This means that, yes, I can’t even debug locally if there’s a warning — but the discipline is worth it. It means that whenever my app is actually running, there are not even any warnings. Instruments Instruments is wonderful. It’s a very good idea to check how much memory your app allocates, and it’s super-important to check for leaks. And if you’re getting crashes, it’s a good idea to use the Zombies tool. Your problem might not be related to zombies, but, when in doubt, it’s worth ruling out.

Posted by on 10 June 2015 | 5:13 pm

Resigning from Q Branch

When I decided to resign from Q Branch I made it clear to my partners that it wasn’t about our software or about them. I love Vesper and working on Vesper, and working with John and Dave has been great. We’re a fantastic team. I decided to leave because I wasn’t working on the software that I’ve been obsessed with for more than a decade. I turned 47 a little while ago, and I’ve had some reasons to reflect on the shortness of life, and I realized how very important it is for me to work on the software that I think about every day. I kept putting it off, but every day that I put it off hurt more than the previous day. I realized that I couldn’t continue — I have to do the work that I need to do. That software is — most likely (plans can always change) — two new Mac apps, and they’re related to each other. They will be Ranchero Software products, which means the team is me and my wife Sheila. One app will be open source, the other commercial. (Again: most likely. Things can change.) I’ll say more about them when the time comes. For now, though: if you’re a Vesper user, and you’re disappointed that I won’t still be working on it, please know that Vesper will continue in good hands — and I think you’ll appreciate the apps I’m working on now. This was a tough decision, and I made it slowly and carefully and with not a little bit of soul-searching. But, having made it, I’m so happy now to be working on the apps I was born to write. P.S. I didn’t mention Omni in the above. Just so it’s clear: I plan to remain at Omni until the day I retire. Working at Omni is rewarding by itself — great team, great apps, fun place — and it also allows me to work on my own apps without needing to make money from them. This gives me extraordinary creative freedom, and I’m going to use it.

Posted by on 2 June 2015 | 12:34 pm

How Not to Crash #7: Dealing with Nothing

Consider this line of code: [thing doStuff]; If thing is nil, it’s no problem. No crash. Nothing at all happens. But you can’t generalize from that that nil is okay in all cases: [self doStuff:thing]; If thing is nil, then what happens? If depends on the implementation of doStuff: — it might crash. Consider this code: menuItem.title = thing; If menuItem is an NSMenuItem, then it crashes when thing is nil. The header for NSMenuItem doesn’t say that, and the documentation only hints at it (“If you do not want a title, use an empty string (@""), not nil.”) This means you need to make sure thing is non-nil. You may be quite certain that it’s non-nil. But consider a case I once fixed, where thing was the name of a font. There was no reason for me to expect that the system API for getting a font name would ever return nil — except that it did, sometimes (rarely, of course, and never on my machine, no matter what I did). Things to know: Nil receivers are okay — as long as your code is okay with nothing happening. Nil parameters may or may not be okay. When calling system APIs, the headers and documentation don’t always tell you what could happen. (This may change when they make greater use of nullability annotations.) Trust no one. Assertions Assertions are a great way of documenting assumptions and requirements, and of making sure those assumptions are true. Assertions should not run in the release build (see the ENABLE_NS_ASSERTIONS Xcode setting). One of my favorites is NSParameterAssert, which I use almost exclusively as a nil check for parameters that must not be nil. It’s super-easy to use: - (void)someMethod:(id)someParameter {   NSParameterAssert(someParameter);   …do whatever… } In the future I’ll probably start using nullability annotations and NSParameterAssert. Both. (I’ll also write some Swift code in the future, which is a whole other thing when it comes to nil. But I’m not talking about that today, partly because I’m not yet enough of an expert in Swift to have good advice.) I also use NSAssert fairly often. NSAssert takes an expression, and a comment — but I’m lazy, and I make the comment nil. (Which is fine in this case.) NSAssert(something == somethingElse, nil); (A note about laziness: the lazy programmer doesn’t write crash bugs, because they don’t want to fix them later.) My favorite crashing bug Years ago, my app NetNewsWire had a crash-log catcher. At launch it would grab the latest crash log from disk and offer to send it to me. With some OS X release (10.5, I think) Apple changed the format for crash logs on disk. I think they had been one file per app, and Apple switched to one file per crash. I had to write new code to handle the new format. I made the change. It went to beta testers, who used the app extensively. Weeks passed. All good. Then, on the day I released this version, I got a ton of reports from people who said, “It’s crashing on launch! But it works fine after launching it again.” Here's the deal: the new code crashed when there were no crash logs at all. And then, on the next launch — now that there’s a crash log — it would not crash. (Yes, a self-healing crashing bug. In the crash log catcher. Such meta.) Of course this meant that it crashed immediately for all new users, not just for people who’d been lucky enough never to get a crash. This was a big reminder to me: always consider the case where there’s nothing. Nothing happens all the time. Nothing is pretty normal. But it might take special handling, and it should always be considered. A less cool crashing bug I don’t think this shipped — I think it was just in beta code. Vesper syncing talks to a server. The server returns JSON data. The Cocoa JSON deserializer turns JSON nulls into NSNull objects. Vesper was expecting an NSString, and got an NSNull. Vesper tried to call a string method on that NSNull, and it crashed. On the surface this seems like a tough case, because you can’t be sure that the type of a given object in JSON text will be what you expect. You’re looking for a string and you get an NSNull. Well, NSNull is one of those things you want to keep as isolated as possible. It’s a walking code smell (though I don’t know what an alternative would be in the case of JSON nulls). (And you should never deliberately use it outside of JSON. Almost never. Super-duper-rare. Like once every few years, and only if you really, really have to. Maybe not even then.) This is part of why, as I mentioned previously, I like to turn JSON into intermediate objects. A big part of this is centralizing the handling of NSNull objects — I don’t want them to leak out into other parts of the app, where anything they touch turns stinky. But there’s another point, which is this: whoever wrote the server side is your sworn enemy. He or she hates you very, very much. Now, in the case of Vesper, that was me. But I still have to code as if the server author has my personal and professional destruction as their sole motivation. (Even though I know the guy, and he’s cool. He likes kittens.) And that doesn’t mean just checking for NSNull — which is normal in JSON anyway — but being careful with the types of every single piece of data. Anything could be anything, at any time. (It’s not turtles all the way down. You’re expecting turtles — but that would be too easy. It might be nothing all the way down.) Total other thing Initialize your variables. Just do it. If I had a nickel for every crashing bug I’ve fixed just by initializing a variable to nil — well, I’d have some nickels. You want zero nickels. Not initializing your variables is like playing with gasoline and saying it’s okay because the matches are in your pocket.

Posted by on 29 May 2015 | 12:35 pm

How Not to Crash #6: Properties and Accessors

This gives me the willies: - (void)someRandomMethod {   some stuff…   _thing = otherThing;   other stuff… } You could prove that it’s correct. You’re using ARC, so the proper retains and releases are added. And nobody is observing _thing. Fine. It’s legal and it works. Say you realize that thing should be observable. So every place you set thing, you bracket the call: [self willChangeValueForKey:kThingKey]; _thing = otherThing; [self didChangeValueForKey:kThingKey]; Also legal, also works. The problem is the future: later today, tomorrow, or in six months, you or somebody else writes a custom setter for thing — maybe because you need something like self.needsDisplay = YES when thing is set — and now you have a bug where the view doesn’t redraw whenever thing changes. Or worse: perhaps that future custom setter tears down an observer and sets up a new one whenever thing changes. Since you’re setting _thing directly, the observations won’t be maintained properly, and you’ll get crashes. The answer is a simple rule: use the accessor when getting and setting properties. In other words, do this: - (void)someRandomMethod {   some stuff…   self.thing = otherThing;   other stuff… } This works whether or not you have a custom setter. When setting thing, you don’t have to care one way or the other. (Here’s the simple test of a programming rule: if you can’t go wrong by following it, but you can go wrong by not following it, then you should follow it.) (Don’t worry about the performance issue of going through accessors. I’m a performance junkie, and I’ve never seen this become a problem. If your app develops performance issues, profile it and find out the real cause.) Exceptions You should not go through the accessor in four places: init methods, dealloc, custom getter, and custom setter. This avoids side effects. If you need a side effect — removing an observer, for instance, in dealloc — that you’d normally place in the setter, make it a separate method and call it from the setter and from dealloc. (Also consider that adding and removing observers outside of init and dealloc is a possible sign that your code needs refactoring.) Auto-synthesize Don’t create instance variables, ever. Declare properties instead. Properties auto-synthesize instance variables. Use @synthesize only when Xcode tells you you need to. Use ARC And if you have non-ARC code, upgrade it to use ARC. Manual memory management is error-prone. Even someone with years of experience will make mistakes from time to time, and mistakes can cause crashes (or memory leaks or abandoned memory, at best). Normally I don’t advocate editing working code that’s running fine — but if you have code that needs maintaining, do yourself and your co-workers a favor and convert it to ARC. (Everybody is going to get worse at manual memory management over time. And there are no points added for being a hero.) (It is possible to run into performance issues with ARC, particularly if you’re dealing with lots of objects in a loop. Remember to use autorelease pools. And don’t jump to conclusions: use the profiler.) (Also: the ARC converter may not always do what you want. If you use it, check the changes it makes. Remember that you can convert one file at a time. Targets can have both ARC and non-ARC files.) Don’t do->this This gives me the screaming meemies: thing->property. No. dealloc If you don’t need dealloc (since you’re using ARC), then don’t create it. There’s no need to set properties to nil in dealloc. A big exception is delegates: nil out the delegates. Use weak Weak is awesome. Delegates, for instance, should be weak. Parents should retain their children, but children should have a weak reference to their parents (if they have a reference at all). Weak gets you out of those invalidate methods where you break retain cycles. Do not, under any circumstances whatsoever, use unsafe_unretained. It’s a trap. You might as well do this: #define CRASHING_BUG unsafe_unretained It’s literally called unsafe. Don’t run with scissors. Heck — don’t even touch these scissors. They have a bunch of poison on them.

Posted by on 27 May 2015 | 3:37 pm

How Not to Crash #5: Threading, part 2

My previous post about threading left open the question of how code running outside the main thread communicates — safely — back to the main thread. The object creating the background task handles the result of the task. This is a hard rule. Usually the object creating the task is an object that lasts for the lifetime of the app. An example might be an image cache — the cache may get emptied during the lifetime of the app, but the cache object lasts for the duration. Another example is something like Vesper’s VSAccount object. There’s always a single VSAccount instance. The user may or may not have a server account. The user may change which server account they’re using. But there’s a single VSAccount object which lasts for the lifetime of the app. (Note: obviously, an app that manages multiple accounts would do things differently. But Vesper manages at most one server account, so this works perfectly well. In Vesper’s case, multiple accounts falls under the YAGNI rule.) The VSAccount object is responsible for sending http requests to the server and handling the result. It turns JSON into intermediate objects on a background queue. It calls the JSON processor with NSData-to-process and a callback block. When the processor is finished, it calls that block on the main thread: if (callback) {   dispatch_async(dispatch_get_main_queue(), ^{     callback(parsedObjects)   }); } This is such a common pattern for me — calling a block that takes one parameter on the main queue — that I have a common function for it. The JSON processor really just does something like this: BSCallBlockWithParameter(callback, parsedObjects); BSCallBlockWithParameter looks something like this: if (!callback)   return; } dispatch_async(dispatch_get_main_queue(), ^{   callback(parsedObjects); }); I use this all the time. Super handy. The key to making this work I don’t ever want to worry that the object that created the background task might go away, so I create background tasks only from objects that last the lifetime of the app. You don’t want to get into the situation where an object that creates a background task goes away (or is torn-down partly or completely) before that task is finished and calls back. It’s a potentially complex subject, and I don’t even want to think about it. (I hate the weak-self dance, for starters.) And that’s exactly the mindset you need when writing code that doesn’t crash: if something is complex, then it’s error-prone. Find a way to make it drop-dead simple. (You could figure out a complex thing and prove that it’s correct — but will you have doubts later and feel the need to audit that code? Will it break if you breathe on it wrong? Or if someone else touches it?) So I do the simple thing: use objects that won’t get deallocated. But there’s an escape hatch worth remembering: a callback block can call class methods and C functions safely. Instance methods are unsafe if the instance disappears — but class methods and C functions are conceptually safe to call. I don’t use this knowledge very often, but I have found it useful from time to time. Use sparingly if at all.

Posted by on 26 May 2015 | 1:23 pm

How Not to Crash #4: Threading

Here’s a simple rule: do everything on the main thread. Machines and devices are so fast these days that you can do more on the main thread than you think you can. It’s a kind of paradise when you don’t have to think about concurrency because there isn’t any. But… I’m a performance junkie. Or, more to the point, I’m a user experience junkie, and the only thing worse than something being slow is being slow and noticeably blocking the main thread. Don’t do that. I’ll get to that. But let’s start with the main thread. The Main Thread Rule All the code I write expects to run on the main thread and on the main thread only, with exceptions. (We’ll get to the exceptions in a minute.) This solves a bunch of problems. For instance, I wrote in an earlier post about unregistering for notifications in dealloc. A few people pointed out that you can’t guarantee on which thread dealloc will be called — but you can, actually, for any given object that runs on the main thread and is referenced only on the main thread. It also means that any KVO changes are posted on the main thread, and any observing objects are also running on the main thread and expecting notifications on the main thread. The benefits of not having to deal with concurrency are tremendous. I strongly suggest writing your entire app this way, and then testing to see if there’s anything that blocks the main thread. If not, then it’s golden, and you should ship. (Test with suitably large data, of course.) Objects That Live in Their Own Little World If — and only if — you find that the main thread is noticeably blocked should you look for ways to un-block it. The first candidates are transformations that can be completely isolated from the rest of your app. I’ll use the example of processing JSON. When I get JSON from a server, I like to turn it into intermediate objects that later get merged into model objects. Reasons: I don’t want the model objects to know about JSON. I want to deal with NSNull values, date conversions, and all other transformations before any other object sees the data. So I use an NSOperationQueue or GCD queue (usually the latter, these days) to turn NSData returned by a server into intermediate objects. (Always use a queue. Don’t ever use detachThreadSelector or performSelectorInBackground.) These intermediate objects will be accessed by one thread at a time. They’re created on a background thread and then passed to the main thread, where they’re used to update the model and then discarded. Because they are referenced on different threads during their lifetimes, I make sure that these objects never know about anything except themselves and what’s passed into their init methods. Once created on the queue, they’re immutable. They don’t observe anything and nobody should observe them (they don’t change, after all). (This makes those objects fully thread-safe in the sense that objects that can’t change are thread-safe. However, it’s not necessary to stress the thread safety, because what’s important is that they’re safe to use on a single thread at a time, rather than on multiple threads at a time.) Objects With Friends Sometimes a number of objects work together. Instead of JSON, think of an RSS parser. In this example, there are three main objects involved: a SAX parser wrapper, its delegate, and the intermediate objects the delegate creates. (Conceptually exactly like the objects from the example above.) The SAX parser wrapper and its delegate live for the length of the operation. They don’t need to be thread-safe, even though the code is run on a separate thread — because they are accessed only on that thread. While they’re working, they know nothing about the outside world, and the outside world knows nothing about them. The SAX parser wrapper knows about the NSData it was initialized with, and it knows it has a delegate. The SAX parser delegate knows about the intermediate objects it’s creating. The intermediate objects don’t know about anything. So these objects work together, but, importantly, they never use KVO or notifications in any way. Instead they use the delegate pattern (whether via blocks or methods isn’t conceptually important). The objects work together, but as loosely as possible while still keeping the group isolated to its task. In the end, only the intermediate objects survive — they’re passed to the main thread, where they’re used to update the model. And then they’re discarded. Worst-Case Scenario I’ve used the phrase “update the model” several times and mentioned doing it on the main thread. A few years ago I would never have dreamed of that — but computers and devices have gotten so much faster that it’s worth going main-thread-only at first, and considering alternatives only after dealing with everything else that can and should be safely moved to a queue. You really don’t want to update model objects on background threads. It’s a crash-making machine. But testing and profiling may tell you that you need to. Try to break down the problem. If updating the model is okay except for this one thing — something that involves turning NSData into a UIImage or NSImage, for instance — then move just that slow part to a background task. (Creating an image from data or a file is a perfectly good thing to move off the main thread. It’s easily isolatable.) It could be that the problem is the database: perhaps you find that it’s otherwise fast to create objects and update properties in memory, even a whole bunch of them. In that case, you might do what I do, which is de-couple the database calls from the main thread. (It’s not that hard: the database code needs to run on a serial background queue, and it should do everything in the exact some order that things happen in the main thread.) Which is to say: there are options. But if you still find that you have to update the model on a background thread, then you just have to do it. Remember that the rest of your app is on the main thread, so when posting notifications and so on, do so on the main thread. Summary Do everything on the main thread. Don’t even think about queues and background threads. Enjoy paradise! If, after testing and profiling, you find you do have to move some things to a background queue, pick things that can be perfectly isolated, and make sure they’re perfectly isolated. Use delegates; do not use KVO or notifications. If, in the end, you still need to do some tricky things — like updating your model on a background queue — remember that the rest of your app is either running on the main thread or is little isolated things that you don’t need to think about while writing this tricky code. Then: be careful, and don’t be optimistic. (Optimists write crashes.)

Posted by on 22 May 2015 | 4:46 pm

How Not to Crash #3: NSNotification

In general, I prefer NSNotification to KVO and (especially) to bindings. I do use KVO sometimes — there are times when it’s the most sensible thing. But NSNotification, like many older APIs, is easier to use without crashing. But you still need to be careful. The One Way to Crash When an object registers for a notification, and then is deallocated without unregistering, then the app will crash if that notification is posted. That’s the thing you need to avoid. The rest of this article describes how to do that. The Big Rule I have one simple, hard-and-fast rule: NSNotifications are posted on the main thread only. No exceptions. If some code is running in another thread and it needs to post a notification, it does so on the main thread. This avoids all problems with notifications coming in on threads you don’t expect. It avoids race conditions with unregistering for notifications. Almost all of an app’s code should be written to run on the main thread. Code that runs in an NSOperation or GCD queue should be isolated from everything else, and should use a delegate pattern (with or without blocks) when multiple objects work together. Ensuring that notifications are always posted on the main thread ought to be easy. (I’ll do another how-not-to-crash article on threading and queues that goes into more detail.) Blanket Unregistering Some people like the extra housekeeping work of unregistering for each NSNotification explicitly in dealloc. You get things like this: [[NSNotificationCenter defaultCenter] removeObserver:self name:kSomeNotificationName object:someObject]; [[NSNotificationCenter defaultCenter] removeObserver:self name:kSomeOtherNotificationName object:someOtherObject]; etc... You can prove when you write this that it’s correct. But it’s not enough to think of a snapshot of your code — you have to think about your code as it moves through time. And future you or future somebody else might add another notification, and not remember to call removeObserver for that specific notification. And then there’s a crash. The other problem is that future coder may have to go through your code and do an audit to make sure each registered observation is removed. This is a pain: it’s manual and error-prone. Instead, always do this: [[NSNotificationCenter defaultCenter] removeObserver:self]; It’s what Indiana Jones would do. Beware Double Registrations If an object registers for a notification, and then registers for it again, the notification handler will get called twice. There’s no automatic coalescing. (This used to happen in the old days on iOS a lot with viewDidLoad. People would put registration code there — but remember that views could get unloaded and reloaded, which meant multiple registrations for the same notification.) Your notification handlers should be written so that they can deal with getting called twice. And it should be impossible for a given object to register twice for the same notification. Both. Register in init, unregister in dealloc In almost every single case, I register for observations in an init method and remove observations in dealloc. If I find that an object needs to add and remove observations during the lifetime of the object, then I consider it a strong code smell. There’s a good chance that 1) either it doesn’t really need to do that, or 2) the object should be split into smaller objects. You know that an init method will be called just once for a given object. You know that dealloc will be called just once when there are no other references to that object. You can use this knowledge to balance out registering and unregistering without having to think about it or keep track of it. So easy. Avoid addObserverForName Some people like -[NSNotificationCenter addObserverForName:​object:​queue:​usingBlock:]. It feels modern because it’s block-based, and we all love blocks. (I sure do.) But it’s a bad idea. You may have saved yourself writing a notification handler method, but you’ve made your housekeeping worse because now you have an extra object to keep around and do a removeObserver: on later. That means no blanket unregistering; it means you’re back to doing audits; it means you have another thing to get right. You might like that the block-based version means you can keep the registration and the notification handler together — but the cost is too high in housekeeping and potential crashes.

Posted by on 21 May 2015 | 4:36 pm

How Not to Crash #2: Mutation Exceptions

You get a collection from somewhere and enumerate it — and then you get an error about the collection being mutated as it was being enumerated. The app crashes. You can avoid this unhappy fate with one simple trick: don’t enumerate mutable collections. Disagree with me You might hold the reasonable position that the real answer is not to mutate a mutable collection while enumerating it. You should have enough understanding of your app to be able to write code that safely enumerates a mutable collection. Yes, you should. You absolutely should. However: writing crash-free code is about removing doubt. It’s about minimizing the chances for errors, and minimizing the chance that future changes (by you or somebody else) introduce a crash. Mutable collections should not be part of public API It should be extremely rare — or, better, never — that an object has a public property that is a mutable collection. Mutable collections should be internal to the object. (Furthermore, as much as possible, public collections should be read-only. This isn’t always possible, of course.) Now, it’s entirely likely that an object has a public collection that is internally a mutable collection. Think of an object that tracks operations. It might make the following public: @property (nonatomic, readonly) NSArray *operations; And internally there’s this: @property (nonatomic) NSMutableArray *mutableOperations; - (NSArray *)operations {   return self.mutableOperations; } That’s perfectly legal code: because mutableOperations is an NSMutableArray, it’s also an NSArray. (I did it this way for years. I thought to myself, “Hey, I’m a grownup. I can handle it.” But what I didn’t realize was that grownup developers write code to make errors less likely.) Properties specified as immutable should be immutable in fact In the above example, you’re advertising operations as an array that can be enumerated safely at any time. Another person — or you yourself, looking at this in six months — won’t necessarily realize that really you’re getting back a mutable array that can’t necessarily be safely enumerated. Here’s the truth-in-advertising solution: - (NSArray *)operations {   return [self.mutableOperations copy]; } (It wouldn’t hurt to modify the property declaration also to make it clear that it’s a copy, but I admit that I don’t always do that. It would have the advantage of making it completely clear to the user of the API what’s going on.) You might push back, citing performance or memory use issues or both — but I’ll admit something: I’m a performance junkie, and I spend an inappropriate amount of time in Instruments making sure things are fast and use a non-weird amount of memory. And I’ve never, ever found this to be a problem. If your app has performance or memory use issues, the problem is something else, not these copies. (Though you might consider using @autoreleasepool so that these copies don’t last very long.) Make the copy. Bonus points: don’t believe their lies I recently fixed a mutation error when enumerating NSTextStorage layoutManagers: @property (readonly, copy) NSArray *layoutManagers; Obviously it’s safe to enumerate. It’s an NSArray, it says, and it’s a copy. Cool. Enumerate away. But it’s a lie. In the debugger I found that it’s an NSMutableArray (__NSArrayM) — and that it’s not a copy at all. It’s NSTextStorage’s _layoutManagers instance variable, which is declared as an NSMutableArray. And some code in my enumeration block did a thing that triggered a mutation in layoutManagers, and the app crashed. The answer: enumerate a copy of layoutManagers. Problem solved. There’s a general point: if you’re getting a collection from code that isn’t yours, it doesn’t hurt to be defensive and enumerate a copy.

Posted by on 16 May 2015 | 11:48 am

How Not to Crash #1: KVO and Manual Bindings

I’ve been fixing crashing bugs recently — but rather than write about fixing crashing bugs, I thought it would be more interesting to write about not creating crashing bugs in the first place. In this first installment I’ll talk about KVO, manual bindings, retain cycles, and invalidate methods. Bindings means never having to say goodbye iOS developers don’t have this, but Mac folks do: we can bind a property to another property. We can make it so that if updates, then updates too. NSKeyValueBinding.h is in AppKit. Take a look at bind:​toObject:​withKeyPath:​options: Let’s imagine a button with a title property. That title property should update whenever some controller’s title updates. Let’s say the controller owns that button. You might write code like this: static NSString *kTitleKey = @"title"; [self.button bind:kTitleKey toObject:self withKeyPath:kTitleKey options:nil]; Very convenient, and it works wonderfully. And you’re well on the road to crashing. Here’s the problem: the binding retains the toObject object. Which means that the button effectively retains the controller. If the controller retains its button (it should), then there’s a retain cycle. Neither will become zombies, but they could become abandoned. One way to crash — and this is a true story — is if the abandoned controller listens for a notification (call it BSNotification), and it Does Something when receiving a BSNotification, and when it Does Something it crashes, because it’s no longer conceptually valid and it doesn’t know how to deal with the current state of things. KVO means having to do everything perfectly every time Let’s add a third object, a model object. What we really want is this flow: modelObject.title changes, which updates controller.title, which updates button.title. We’ll use KVO this time. In the controller: - (NSString *)title {   return self.modelObject.​title; } + (NSSet *)keyPaths​ForValues​AffectingTitle {   return [NSSet setWithObject:​@"modelObject.title"]; } Okay — now we have the entire flow. When modelObject.title changes, that affects controller.title, and button.title updates with the correct value. Very convenient, and it works wonderfully. It will crash, of course, when modelObject is deallocated (because an instance of modelObject was deallocated while it still has an observer). If, instead, controller is retaining modelObject (as it probably should be), then you have a third object that will be abandoned and never deallocated, and it will sit around stewing and growing eviler by the minute. One way to solve the problem that isn’t that great The controller could have a method with a name like invalidate that breaks the retain cycles. Once broken, then dealloc will eventually be called for the controller, its button, and its model object. You might write code like this, which you call when you know for a fact you’re finished with the controller: - (void)invalidate {   [self.button unbind:kTitleKey];   self.modelObject = nil; } Here’s why this solution isn’t great: Reference counting is a nice solution — it guarantees that when dealloc is called, you know that no object has a strong reference to the object being deallocated. This makes dealloc a great place to remove observations and similar that need removing. But if you use something like an invalidate method, you’re trying to do the work of reference counting yourself. You have to call invalidate, and you have to call it at the right time. Can you make that guarantee forever, for every object that has an invalidate method? What if something changes so that more than one object retains the controller? Who calls invalidate, and when? That’s a lot of extra work and thinking, and part of the goal of programming is to make errors less likely. Relying on invalidate makes errors more likely. A better way to solve the problem Let’s go back to the problem we’re trying to solve: modelObject.title changes, which updates controller.title, which updates button.title. Let’s also be clear: controller knows about modelObject and button, but neither of those two know about each other, and neither of those two know about the controller. Here’s how we might handle it without the need for an invalidate method. In the controller, nuke the custom getter. Nuke keyPaths​ForValues​AffectingTitle. Nuke the use of bind:​toObject:​withKeyPath:​options:. Instead, create a custom setter — because, after all, setters are called when something changes, and the entire problem to solve is propagating changes to a title property. - (void)setTitle:(NSString *)title {   _title = title;   self.button.title = title; } That solves half the problem: when controller.title changes, button.title changes. We can’t do something similar with modelObject, since it doesn’t know about the controller. Instead, have the controller observe modelObject.title. [self.modelObject addObserver:self forKeyPath:​kTitleKey options:0 context:​kTitleContext]; Then in the KVO observation method, watch for kTitleContext, then do self.title = self.modelObject.title. This will call the controller’s setTitle: — which then updates button.title. With this solution there are no retain cycles. There is one line of tear-down work to do, but you can do it in the controller’s dealloc method: [_modelObject removeObserver:​self forKeyPath:kTitleKey context:​kTitleContext]; Review and recommendations The solution we came up with fixes the retain cycle without your having to remember to call an invalidate method and call it at the exact right time. It’s safer code. There’s a good chance it’s less code, too, and it’s more explicit code. Some recommendations: Don’t use bind:​toObject:​withKeyPath:​options: ever, in any circumstance. (iOS people: consider yourselves lucky that it’s not an option. Also consider that there’s probably a reason it never made it to iOS.) Use a custom setter rather than a custom getter when you’re propagating changes. (It’s in the setter where a thing changes, after all.) Avoid invalidate methods in favor of letting reference counting do its thing — because if you are the one trying to track references, you’re going to make mistakes. (I realize avoiding invalidate methods isn’t always possible, but it’s probably more possible than you think it is.) Interlocking observations of any kind make it difficult to think about what happens in your app: it’s better to be explicit whenever it’s reasonable. Once you get enough of these tendrils of observations you’ve built an impenetrable jungle, and making changes becomes scary. In theory, bindings and KVO are there to promote loose coupling, but in practice the coupling is often just as tight — if not tighter, in a sense — and harder to debug and get right. It’s generally best to do explicit observations (as opposed to keyPaths​ForValues​AffectingXyz) and keep your keyPaths free of . characters.

Posted by on 14 May 2015 | 5:20 pm

No Forgiveness

I was a fan of Alex Rodriguez when he was a Mariner. And I would have remained a fan when he left for the Rangers — because that’s baseball. Good and beloved players sometimes change teams. I remained a fan of Ken Griffey, Jr., Randy Johnson, and Ichiro Suzuki after they switched teams. But there was this in 2001: A-Rod believes Boeing should follow him to Texas. That comment from the former Mariners shortstop came up during a segment of CNBC’s show “Squawk Box” featuring Boeing Chairman and CEO Phil Condit. A-Rod was quoted on the show as making this pitch to Boeing, “I moved to Dallas-Ft. Worth to improve my future… so should you.” It’s one thing to move to another team and say goodbye to your fans — those fans who were the first to cheer for you — many of whom were Boeing employees. It’s quite another thing to take a shot at the livelihood of those fans. What an insult. Fuck him. I’m still disgusted. And I was not surprised to find out he was a cheater. Not a man.

Posted by on 8 May 2015 | 4:36 pm