<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ahruman’s Webthing &#187; Code</title>
	<atom:link href="http://jens.ayton.se/blag/tags/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://jens.ayton.se/blag</link>
	<description>Cocoa coding stuff, when I can be bothered.</description>
	<lastBuildDate>Thu, 25 Aug 2011 21:56:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>On the Mac App Store</title>
		<link>http://jens.ayton.se/blag/on-the-mac-app-store/</link>
		<comments>http://jens.ayton.se/blag/on-the-mac-app-store/#comments</comments>
		<pubDate>Fri, 22 Oct 2010 10:45:47 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Politics]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/?p=110</guid>
		<description><![CDATA[When the Mac App Store was announced, I said to someone, “‘Convenient’ isn’t the same as ‘good for you’.” This might look slightly odd in a community dedicated to improving people’s workflows, so I’d like to expand on it. (I &#8230; <a href="http://jens.ayton.se/blag/on-the-mac-app-store/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>When the Mac App Store was announced, I said to someone, “‘Convenient’ isn’t the same as ‘good for you’.” This might look slightly odd in a community dedicated to improving people’s workflows, so I’d like to expand on it. (I should point out that I myself don’t make any money on software and don’t particularly care how big my audience is, so I’m approaching this as an aware consumer.)</p>
<p>My position on convenience is this:</p>
<ul>
<li>Good user experience is the convenience of not having to use a difficult and dangerous hand crank to start your car.</li>
<li>The Mac App Store is the convenience of having McDonald’s open in your apartment building.</li>
</ul>
<p><span id="more-110"></span>
<p>Of course, everyone is free not to eat at McDonald’s exclusively, or even at all. But this is beside the point. The vast majority will appreciate the convenience, and grow accustomed to it. Soon, the idea of looking elsewhere for food will seem odd. The more adventurous will consider, perhaps, an occasional excursion to the nearby Burger King of Steam or other big brands, but the existence of more obscure alternatives will be little more than a strange piece of trivia. The McDonald’s in your apartment building will have a <i>de facto</i> captive audience.</p>
<p>The captive audience will have little grasp of what the limitations on their diet are, or whether the new baconburger of the week represents the true leading edge of hamburger innovation. They will have no idea whether the prices they are paying are fair, since there will be no market to compare with. If they want organic wholemeal buns with walnuts in, they’re out of luck, because their McDonald’s is doing fine selling the normal kind.</p>
<p>In short, with an effective monopoly on distribution, innovations that reach outside the box of the App Store agreement will not reach users, and there will be no incentive for Apple to cooperate in expanding the box.</p>
<p>I’m not a free market fundamentalist, but I will only approve of a monopoly if there is good reason to believe it will benefit consumers or the population at large in the long term. The App Store doesn’t come close. (Apple’s policy of rejecting apps that are “too similar” to ones already in the store ensure a true free market cannot develop <em>within</em> the store either.)</p>
<p>In the case of the iPad, my requirement as a potential customer has been a side-loading option of some sort, despite the knowledge that it would be very hard to be competitive outside the App Store. It is fundamental that I, as the owner of my hardware, can decide whether I want to install whatever software exists.</p>
<p>But for the Mac, coming at this distasteful compromise situation from the other direction is unacceptable. If the App Store succeeds – and it will, once the stupidity of the distribution agreement is reduced by the smallest possible amount – my next computer will not be a Mac. I will abide inferior, noisy hardware running inferior, noisome software before I abide a cage, be it ever so shiny.</p>
<p><small>For the record: no, I’ve never owned a game console.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/on-the-mac-app-store/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Almost elegant cave man debugging</title>
		<link>http://jens.ayton.se/blag/almost-elegant-cave-man-debugging/</link>
		<comments>http://jens.ayton.se/blag/almost-elegant-cave-man-debugging/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 19:43:20 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/?p=103</guid>
		<description><![CDATA[Recently, the Twitternets pointed me at Vincent Gable’s blog post, The Most Useful Objective-C Code I’ve Ever Written. It is indeed quite useful; given a semi-arbitrary expression, it prints out the value, using @encode() and macros to minimize drudgery. However, &#8230; <a href="http://jens.ayton.se/blag/almost-elegant-cave-man-debugging/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently, the Twitternets pointed me at Vincent Gable’s blog post, <a href="http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/comment-page-1/">The Most Useful Objective-C Code I’ve Ever Written</a>. It is indeed quite useful; given a semi-arbitrary expression, it prints out the value, using <code>@encode()</code> and macros to minimize drudgery.</p>
<p><span id="more-103"></span>
<p>However, it’s limited to a fixed set of types. As Vincent points out, this could be avoided by parsing the <code>@encode()</code> string rather than recognising specific strings. As it happens, I had a partially working parser. It is now wholly working and added a convenience macro similar to Vicent’s, and you can find it <a href="https://github.com/Ahruman/JAValueToString">here</a>. It handles most structs, unions and arrays automatically. It’s still not entirely general, though, in part because of compiler limitations:</p>
<ul>
<li>Bitfields aren’t supported. This is basically because I haven’t bothered. I’m not clear on whether the encoding actually provides enough information to handle these properly, though.</li>
<li>Altivec and SSE vector types aren’t handled, because <code>@encode()</code> completely ignores them – if you have a <code>struct { int a; __m128 v; int b; }</code>, the encoding is <code>{?=ii}</code>, as if the vector wasn’t even there.</li>
<li>Aggregate types with non-standard alignment (<code>#pragma pack</code>) are not supported. Again, the compiler doesn’t encode the necessary information.</li>
</ul>
<p>The latter two cases could easily lead to crashes if left to their own devices. My solution is to first parse the entire type without reading any data, to ensure that the amount of data the parser will consume matches the size according to <code>sizeof()</code>, then reparse if the size matches.</p>
<p>There are probably cases it doesn’t handle. Bug reports would be welcome. Also, it doesn’t handle PPC-64 and ARM, because I don’t have suitable machines to extract alignment information on and I can’t be bothered to read actual documentation.</p>
<p><b>Update (2010-08-22):</b> Added support for <code>_Complex</code> types (encoded as <code>'j'</code>; a <code>complex double</code> is encoded as <code>jd</code> and stored the obvious way, as two doubles in a row).</p>
<p><b>Update (2010-08-23):</b> Fixed alignment calculations for nested structs when alignment is not determined by first member.</p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/almost-elegant-cave-man-debugging/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Proposal: generics (and some other stuff) for Objective-C</title>
		<link>http://jens.ayton.se/blag/generics-for-objective-c/</link>
		<comments>http://jens.ayton.se/blag/generics-for-objective-c/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 20:38:04 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[flamebait]]></category>
		<category><![CDATA[generics]]></category>
		<category><![CDATA[notc++]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[tl;dr]]></category>
		<category><![CDATA[type system]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/?p=78</guid>
		<description><![CDATA[Some time ago, Greg Parker asked the Twitternets what we’d like to see in a purely hypothetical Objective-C-without-the-C language. Someone — I believe it was Landon Fuller — pointed at an article about the Strongtalk type system for Smalltalk. I &#8230; <a href="http://jens.ayton.se/blag/generics-for-objective-c/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Some time ago, <a href="http://twitter.com/gparker/">Greg Parker</a> asked the Twitternets what we’d like to see in a purely hypothetical Objective-C-without-the-C language. Someone — I believe it was <a href="http://twitter.com/landonf">Landon Fuller</a> — pointed at an article about <a href="http://bracha.org/nwst.html">the Strongtalk type system for Smalltalk</a>. I quite like the idea of Objective-C-without-the-C (i.e., a language that is native to the Objective-C object system and runtime without the baggage of C), but after reading that article I found myself asking why we couldn’t do something similar in Objective-C.</p>
<p>I don’t think my random musings have much influence on the design of the language, but if I don’t write it down nobody’s going to know how nuts I am, so here’s a semi-concrete proposal for contextual types and generics for Objective-C. Since anyone even mentioning generics in the vicinity of Objective-C will inevitably be flamed for trying to turn it into C++, this is followed by an aside entitled <i>Why This is Not the Baby-eating Spawn of Bjarne Stroustrup</i>. (Nothing personal, Bjarne.)</p>
<p><span id="more-78"></span><br />
<h2 id="types-in-objc">Types in Objective-C</h2>
<p>A fundamental characteristic of Objective-C is that it has two separate type systems: the dynamic type system, which applies to objects, and the static type system, which applies to variables (which may or may not refer to objects).</p>
<p>As far as objects are concerned, the static type system is optional — you can refer to any object with the type <code class="objc code">id</code>, except when calling a method whose type may be ambiguous. The static type system is also advisory — it suggests to programmers, the compiler and other tools such as the <a href="http://developer.apple.com/tools/Xcode/">IDE</a> and <a href="http://clang-analyzer.llvm.org/">analyzer</a> what the class of an object may be at runtime, but doesn’t constrain the object. A variable of type <code>NSString&nbsp;*</code> may actually refer to an <code>NSArray</code> at runtime, and method calls will dynamically go to <code>NSArray</code>’s implementation.</p>
<p>My proposal deals only with the static type system. The idea is to provide information that helps the compiler and analyzer check your logic, and the IDE to provide better suggestions. This is done by replacing <code>id</code> with more specific static types in most of the situations it’s used in. The generated code is not affected in any way. The proposal does not introduce bondage and discipline on the language; the new types can always be cast away.</p>
<h2 id="contextual-types">Contextual Types</h2>
<p>By far the most common use of <code>id</code> is as the return type for methods that may return an instance of “this” class, or of the subclass it’s called on. The obvious examples are <code>+alloc</code> and <code>-init</code>.</p>
<p>The IDE and, I believe, the analyzer already use heuristics to determine the return type of <code>+alloc</code> and <code>-init</code>, but I propose formalizing this in code. It would look something like this:</p>
<pre class="objc code" id="contextual-example">@interface NSObject &lt;NSObject&gt;
{
    Class   isa;
}

+ (void)load;

+ (void) initialize;
- ([:Self]) init;

+ ([:Self]) new;
+ ([:Self]) allocWithZone:(NSZone *)zone;
+ ([:Self]) alloc;

// ...

+ ([:Superclass]) superclass;
+ ([:Class]) class;
- ([:Superclass]) superclass;
- ([:Class]) class;

@end</pre>
<p>When calling a class method, <code>[:Class]</code> resolves to the receiver (or, type-equivalently, a pointer to an instance the receiver’s metaclass), and <code>[:Self]</code> resolves to a pointer to an instance of the receiver. <code>[:Superclass]</code> resolves to the superclass of the receiver. For instances, they resolve as for class methods on the class of the instance.</p>
<p>I’m sure some people will object to the conceptual purity of this design, and possibly the names and syntax. The colon is a bit odd — it’s there to avoid ambiguity with generics (see <a href="#generics">below</a>). All of these are minor quibbles; the syntax would need to be reviewed if actually implementing it.</p>
<p>So what’s the point? Consider the following code:</p>
<pre class="objc code">NSString *s = [[NSArray alloc] init];</pre>
<p>As it stands, this is perfectly valid and doesn’t generate a compiler diagnostic. With the addition of contextual types it would, because:
<ul>
<li> The type of <code>+[NSArray alloc]</code> (inherited from <code>NSObject</code>) is <code>[:Self]</code>, which resolves to <code>NSArray&nbsp;*</code>.</li>
<li> The receiver of the <code>-init</code> is thus known to be an <code>NSArray</code>.</li>
<li> The type of <code>-[NSArray init]</code> (inherited from <code>NSObject</code>) is <code>[:Self]</code>, which again resolves to <code>NSArray&nbsp;*</code>.</li>
<li> Therefore, the right hand side of the assignment is of type <code>NSArray&nbsp;*</code>, and the assignment is invalid.</ul>
<p>If, for some reason, you really wanted to do that, you could use an explicit cast to get rid of the diagnostic.</p>
<h2 id="generics">Generics</h2>
<p>The other major use of <code>id</code> is for polymorphic collections. True polymorphic collections are great! But some of the time, you only want to put one kind of object in your collection, and would appreciate the computer doing the drudge work of checking that you didn’t put the wrong stuff in the wrong place.</p>
<p>From the perspective of the previous section, generics are a simple extension to contextual types. Instead of restricting you to <code>[:Self]</code> and the highly specialized <code>[:Class]</code> and <code>[:Superclass]</code>, you can provide one or more class names as a parameter to a type declaration. Example time again:</p>
<pre class="objc code" id="mythingholder-example">@interface MyThingHolder[ThingType = id] : NSObject
{
    [ThingType]     thing;
}

- ([:Self]) initWithThing:([ThingType])thing;

- (void) setThing:([ThingType])thing;
- ([ThingType]) thing;

// Or, for modernists:
@property (readonly, nonatomic) [ThingType] thing;

@end

// ...
MyThingHolder[NSString] *holder = [[MyThingHolder[NSString] alloc] initWithThing:@"foo"];
holder.thing = [NSNumber numberWithBool:MAYBE];      // Warning: type mismatch
holder.thing = (id)[NSNumber numberWithBool:MAYBE];  // OK. (an issue here would be inconsistent with general Objective-C behaviour.)

// Or, equivalently:
typedef MyThingHolder[NSString] MyStringHolder;
MyStringHolder *holder = [[MyStringHolder alloc] initWithThing:@"foo"];</pre>
<p>Some notes: the type parameter can only be a class, since specialized code is not generated for each type. (See <a href="#bjarnespawn">Why This is Not the Baby-eating Spawn of Bjarne Stroustrup</a> below.) Since the type parameter is always a class, I have made the <code>*</code> implicit. This is cleaner, but could well lead to confusion and is quite likely a bad idea. (If only I had a time machine…)</p>
<p>The type parameter has a default value, previously unheard of in Objective-C, so that you can ignore generics and create a “vanilla” <code>MyThingHolder</code> that works just like in traditional Objective-C. This provides an upgrade path for existing classes:</p>
<pre class="objc code" id="collections-example">@interface NSArray[Item &lt;NSObject&gt; = id &lt;NSObject&gt;] : NSObject &lt;NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration&gt;

- (NSUInteger) count;
- ([Item]) objectAtIndex:(NSUInteger)index;

@end

@interface NSArray[Item] (NSExtendedArray)

- (NSArray[Item] *) arrayByAddingObject:([Item])anObject;
- (NSArray[Item] *) arrayByAddingObjectsFromArray:(NSArray[Item] *)otherArray;
// ...
- (BOOL)containsObject:([Item])anObject;
// ...
<span id="decl-arrayWithObject">+ ([:Self[Item]]) arrayWithObject:([Item])anObject;</span>
// ...
<br/>
@interface NSDictionary[Key &lt;NSCopying, NSObject&gt; = id &lt;NSCopying, NSObject&gt;, Value &lt;NSObject&gt; = id &lt;NSObject&gt;] : NSObject &lt;NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration&gt;

- (NSUInteger) count;
- ([Value]) objectForKey:([Key])aKey;
- (NSEnumerator[Key] *)keyEnumerator;

@end

@interface NSDictionary[Key, Value] (NSExtendedDictionary)

- (NSArray[Key] *) allKeys;
- (NSArray[Key] *) allKeysForObject:([Value])anObject;
- (NSArray[Value] *) allValues;
// ...
- (BOOL) isEqualToDictionary:(NSDictionary[Key, Value] *)otherDictionary;
- (NSEnumerator[Value] *) objectEnumerator;
- (NSArray[Value] *) objectsForKeys:(NSArray[Key] *)keys notFoundMarker:([Value])marker;
// ...
- (void) getObjects:([Value] *)objects andKeys:([Key] *)keys;
// ...</pre>
<p>These examples introduce an additional concept: restrictions on type parameters, in this case protocol requirements. The other obvious type of restriction would be a superclass requirement, such as <code>[Type: NSString = NSString]</code>.</p>
<p>Using these genericized versions in the same manner as the existing versions would require no code changes – as long as you’re using them with objects that fulfil the protocol requirements, which already exist but aren’t explicit in code.</p>
<h2 id="type-conformance">Type Conformance</h2>
<p>A fundamental question for static type systems with inheritance is when implicit casts are allowed. There are subtleties here, some of which I probably haven’t considered, and I have a feeling I’ve considered some and then forgotten about them. The most obvious case is when the base type and each type parameter could be validly cast:</p>
<pre class="objc code" id="basic-implicit-casts-example">NSMutableArray[NSMutableString] *a = whatever;
NSMutableArray *b = a;            // OK, b is NSMutableArray[id &lt;NSObject&gt;]
NSMutableArray[NSString] *c = a;  // OK
a = b;                            // Not OK, implicit cast from NSMutableArray[NSString] to NSMutableArray[NSMutableString]
NSArray[NSMutableString] *d = a;  // OK
NSArray[NSString] *e = a;         // OK
id f = a;                         // OK
</pre>
<p>As indicated <a href="#mythingholder-example">above</a>, passing an <code>id</code> when a parameter type is expected is necessary for consistency with Objective-C in general:</p>
<pre class="objc code" id="id-implicit-cast-example">NSMutableArray[NSString] *a = whatever;
[a addObject:[NSNumber numberWithInt:42]];      // Type mismatch, assuming +numberWithInt: is declared to return [:Self]
[a addObject:(id)[NSNumber numberWithInt:42]];  // OK</pre>
<p>How about the case where a method returns an unadorned type?</p>
<pre class="objc code" id="legacy-example">@interface LegacyThing: NSObject
- (NSArray *) legacyListOfStrings;
@end

LegacyThing *l = whatever;
NSArray[NSString] *list = [l legacyListOfStrings];</pre>
<p>In order to minimize the burden of adopting generic syntax, I’d suggest explicitly permitting this, with an optional warning. (The non-generic equivalent, assigning an <code>id&nbsp;&lt;NSObject&gt;</code> to an <code>NSString&nbsp;*</code>, generates the somewhat unexpected warning <i>“type &#8216;id &lt;NSObject&gt;&#8217; does not conform to the &#8216;NSCopying&#8217; protocol”</i> in GCC and nothing in Clang. Assigning an <code>NSObject&nbsp;*</code> to an <code>NSString&nbsp;*</code> generates warnings in both. My proposal is that assigning a <code>T</code> to a <code>T[P]</code> should work without warning by default, even if the default type parameter is a class rather than <code>id</code> with or without protocols.)</p>
<h2 id="bjarnespawn">Why This is Not the Baby-eating Spawn of Bjarne Stroustrup</h2>
<p>Many Objective-C programmers are refugees from the blasted wasteland of C++, and will reflexively cringe at the similarity with templates:</p>
<pre class="objcpp code" id="cpp-vs-objc-example">std::vector&lt;Duck&gt; ducks;
Chicken chicken;
ducks.push_back(chicken);             // Error
ducks.push_back(*(Duck *)chicken);    // Horrible crash here or some time in the future, maybe.

NSArray[Duck] *ducks = [NSArray new];
Chicken *chicken = [Chicken new];
[ducks addObject:chicken];            // Warning: type mismatch
[ducks addObject:(Duck *)chicken];    // No problem, unless you call -quack on it.
</pre>
<p>While the difference should hopefully be clear by now, I’ll spell it out: in C++, <code>std::vector&lt;Duck&gt;</code> creates an entirely new class (with bits of <code>Duck</code> inlined into it). The Objective-C-with-generics version only provides hints to the compiler, so it can catch mistakes. It doesn’t stop you from putting chickens among your ducks, or make the duck array reject chickens at runtime, or generate a new array-of-chickens class.</p>
<p>In <a href="http://lists.apple.com/archives/objc-language/2003/Dec/msg00084.html">earlier discussions</a> of generics, it has been stated that this type of mistake is rare in practice and should be caught with unit tests. If you feel that way, you’re welcome to stick to your current approach, and the introduction of generics, as described, will not affect you.</p>
<p>To avoid ballooning side effects of generics, I’ve deliberately avoided suggesting generic functions and methods (i.e., ones whose return type is dependent on one or more argument types, independent of their class in the case of methods).</p>
<h2 id="one-last-thing">One Last Thing</h2>
<p>An effect of the above is that I want the language to contain types like <code>NSArray[NSMutableDictionary[NSString, NSSet[NSMutableArray[NSNumber]]]] *</code>. That doesn’t mean I want to spend my time <em>typing</em> <code>NSArray[NSMutableDictionary[NSString, NSSet[NSMutableArray[NSNumber]]]] *</code>, even with autocomplete. Fortunately, there exists a well-known solution to this problem: type inference.</p>
<p>If I access a member of an array of the aforementioned sesquipedalian type, I get an <code>NSMutableDictionary[NSString, NSSet[NSMutableArray[NSNumber]]] *</code>. What’s more, the compiler knows this. The benefit of static typing lies primarily in checking what I do with my dictionary, rather than checking that the item I retrieved is what I thought it was, so I should be able to ask it to type a variable appropriately.</p>
<p>I quite like C++1x’s solution of recycling the <code>auto</code> keyword for this use, but that would conflict with Objective-C’s goal of being a strict superset of C. There are various other choices, such as <code>var</code> or <code>any</code> — or maybe <code>ego</code>. In any case, type inference would lead to code like:</p>
<pre class="objcpp code" id="type-inference-example">typedef NSArray[NSMutableDictionary[NSString, NSSet[NSMutableArray[NSNumber]]]] MyHorribleNestedType;  // TODO: replace with sensible model classes.

MyHorribleNestedType *array = whatever;
var element = [array objectAtIndex:0];              // Type is inferred as NSMutableDictionary[NSString, NSSet[NSMutableArray[NSNumber]]]*
var subEntry = [NSArray arrayWithObject:@"bloop"];  // Type is inferred as NSArray[NSString]
[element setObject:subEntry forKey:@"moop"];        // Type mismatch: expected NSSet[NSMutableArray[NSNumber]], got NSArray[NSString]</pre>
<p>A subtlety here: the return type of <code>[NSArray arrayWithObject:@"bloop"]</code> (declared <a href="#decl-arrayWithObject">previously</a>) is <code>[:Self[Item]]</code>, which is inferred from the receiver (the <code>NSArray</code> class object) and argument to resolve to <code>NSArray[NSString]</code>. Instead of <code>typedef</code>ing <code>MyHorribleNestedType</code>, we could have constructed the type implicitly in the same way. like everything else in the proposal, this is optional; if you used <code>id</code> or explicit, unparameterized types in this example, the type mismatch would not be detected, but the generated code would be identical.</p>
<h2 id="summary">Summary</h2>
<ul>
<li> The <code>id</code> type is very powerful and flexible. However, most of the time you don’t need this flexibility, and type checking is helpful — this is why Objective-C has optional static type checking in the first place, and almost all Objective-C code opts in to it.</li>
<li> The proposal would not impose any new restrictions, or any new guarantees. It would only extend (optional) static type checking to cases which are currently not covered.</li>
<li> It would not involve any implicit code generation, and no runtime overhead.</li>
<li> Combined with type inference, it could catch errors without additional code.</li>
<li> There would be no new collections, and no implementation changes to existing ones other than updated type declarations. (Updated headers would work with the existing implementations.)</li>
<li> If you really don’t want static type checking, you can continue using <code>id</code> everywhere.</li>
<li> I mean it about the “optional”. The proposed change would have no effect unless adopted both by a class and its clients. A parameterized collection pointer can be cast to plain one at any time with no cost.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/generics-for-objective-c/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Multi-type Save Panel Controller</title>
		<link>http://jens.ayton.se/blag/multi-type-save-panel-controller/</link>
		<comments>http://jens.ayton.se/blag/multi-type-save-panel-controller/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 19:35:20 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/?p=68</guid>
		<description><![CDATA[As a change of pace, I thought I’d post some code that doesn’t go out of its way to be bad. JAMultiTypeSavePanelController is a class (abstracted from ImageIO Export for Acorn) to handle the case where you want to offer &#8230; <a href="http://jens.ayton.se/blag/multi-type-save-panel-controller/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As a change of pace, I thought I’d post some code that doesn’t go out of its way to be bad.</p>
<p><code>JAMultiTypeSavePanelController</code> is a class (abstracted from <a href="http://jens.ayton.se/acorn/">ImageIO Export for Acorn</a>) to handle the case where you want to offer the user a choice of formats to save in.</p>
<p><img src="http://jens.ayton.se/blag/wp-content/uploads/2009/08/JAMultiTypeSavePanelController.png" alt="Save panel" border="0" style="max-width: 100%" /><br />
<span id="more-68"></span>
<p>It wraps an <code>NSSavePanel</code> and handles all the UTI and extension details. You can provide a customised <code>NSSavePanel</code> or let the controller create one. The only restriction is that the controller appropriates the accessory view. Usage is similar to <code>NSSavePanel</code> itself:</p>
<pre class="objc-code">NSArray *types =
    [NSArray arrayWithObjects:@"com.apple.rtfd", @"public.rtf", @"public.plain-text", nil];
JAMultiTypeSavePanelController *controller =
    [JAMultiTypeSavePanelController controllerWithSupportedUTIs:types];
controller.autoSaveSelectedUTIKey = @"document format"; // Optional: preferences key for selected type.
controller.sortTypesByName = NO; // Optional: show in specified order instead of alphabetically by display name.
[controller beginSheetForDirectory:nil
                              file:@"untitled 42"
                    modalForWindow:docWindow
                     modalDelegate:self
                    didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:)
                       contextInfo:nil];</pre>
<p><code>-runModalForDirectory:file:</code> is also supported.</p>
<p><a href="https://github.com/Ahruman/JAMultiTypeSavePanelController">Code</a> (MIT/X11 license)</p>
 <p><a href="http://jens.ayton.se/blag/?flattrss_redirect&amp;id=68&amp;md5=b81f9f8b25b2704e0274c544cd4b3172" title="Flattr" target="_blank"><img src="http://jens.ayton.se/blag/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/multi-type-save-panel-controller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Constant objects for fun and non-profit</title>
		<link>http://jens.ayton.se/blag/objc-constant-objects/</link>
		<comments>http://jens.ayton.se/blag/objc-constant-objects/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 02:27:05 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[evil]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/?p=45</guid>
		<description><![CDATA[The @&#34;foo&#34; operator for constant NSString objects in Objective-C is extremely convenient. Indeed, if it wasn’t there, programming with Cocoa would be a royal pain. Many of us have at various points wished there was equivalent syntax for NSNumbers, and &#8230; <a href="http://jens.ayton.se/blag/objc-constant-objects/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The <code>@&quot;foo&quot;</code> operator for constant <code>NSString</code> objects in Objective-C is extremely convenient. Indeed, if it wasn’t there, programming with Cocoa would be a royal pain. Many of us have at various points wished there was equivalent syntax for <code>NSNumber</code>s, and possibly collections.</p>
<p>As an early Christmas present to fellow lovers of twisted, evil code that should never have seen the light of day under any circumstances whatsoever, I hereby present an implementation of the first half of that wish.</p>
<p><span id="more-45"></span><br />
<h2>Caveat lector</h2>
<p>Now, when I say it’s evil, I really, really mean it. We’re talking about building objects in the data section of your code by packing structs, thus depending on data layout (and as such, depending on the old 32-bit runtime). We’re talking about nested macros with lots of <code>?:</code>s in them. We’re talking about gcc’s built-in parser pseudo-functions. Hearken to the words of Greg Parker, official Objective-C Runtime Wrangler at Apple:</p>
<p style="margin:0 3em">@<a href="https://twitter.com/gparker/status/1051085472">gparker</a>: @ahruman JANumberLiteral would break in several exciting ways in 64-bit. Might almost be safe enough in 32-bit, though.<br />
@<a href="https://twitter.com/ahruman/status/1051088370">ahruman</a>: @gparker Yeah, I know. I’ll be pasting “If you do this in real life, I’ll have to track you down and shoot you” warnings all over it. :-)<br />
@<a href="https://twitter.com/gparker/status/1052054292">gparker</a>: @ahruman Don&apos;t shoot &apos;em, just maim &apos;em a bit. I want my turn after you&apos;re done.<br />
@<a href="https://twitter.com/ahruman/status/1052079228">ahruman</a>: @gparker That’s what kneecaps were invented for.</p>
<p>Be told.</o></p>
<h2>Overview</h2>
<p>So, all that aside… what we’re looking at here is a macro <code>$N(n)</code> which takes a number and returns an <code>NSNumber</code>. (The convention of using dollar signs for macros implementing desired language features was introduced by <a href="http://mooseyard.com/Jens/">the other Jens A</a>.) If passed a compile-time constant, it will produce a constant object, i.e. a single, immortal instance based in the data section with no instantiation overhead, just like a string object constant. If passed a non-constant, it will give you a normal autoreleased <code>NSNumber</code> instead.</p>
<p>Constant <code>NSString</code>s work by creating a struct with the following layout: <code>{&nbsp;&amp;__CFConstantStringClassReference, 1992, &quot;foo&quot;, 3&nbsp;}</code>, where 1992 is a flag field and 3 is the length of the string. (Note that this is not the <code>NSConstantString</code> from the bottom of NSString.h. I believe this change was made in the OS X 10.2 SDK.) <code>__CFConstantStringClassReference</code> is a symbol exported from CoreFoundation.framework and implicitly declared in all Objective-C or Objective-C++ files by the compiler.<small><sup><a href="#objc-constant-objects-footnote-1" name="objc-constant-objects-footnote-ref-1">1</a></sup></small> My task, once I chose to accept it, was to do something similar for <code>NSNumber</code>.</p>
<p>Trying to build actual <code>NSCFNumber</code>s would be an unnecessary extra evil. Instead, I subclassed the abstract <code>NSNumber</code> twice, once for <code>long&nbsp;long</code>s and once for <code>double</code>s, giving me a known layout to target. The subclasses also override <code>-retain</code>, <code>-release</code> and <code>-autorelease</code> to do nothing, in the manner of a singleton. Then, building an instance is conceptually simple:</p>
<pre class="objc-code">const static struct { Class isa; double value; } fakeObj =
{ [JAFloatNumber class], 42.0 };
NSNumber *number = (NSNumber *)&fakeObj;</pre>
<p>The structure needs to be declared <code>static</code> so that it doesn’t evaporate at the end of the containing scope. This presents a dilemma, however: static initializers must be constant expressions, and a method call doesn’t qualify. Besides, we want the object to be constant data.</p>
<p>Luckily for us, classes are represented by global symbols like any other. Well, almost like any other. Unlike symbols based on C identifiers, their linker symbols don’t start with an underscore but with a dot, meaning you can’t reference them the usual way. Fortunately, gcc provides us with a solution in the form of <a href="http://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/Asm-Labels.html">asm labels</a>:</p>
<pre class="objc-code">extern const struct objc_class JAFloatLiteralClassObject
        __asm__(&quot;.objc_class_name_JAFloatNumber&quot;);</pre>
<p>The basic implementation then becomes:</p>
<pre>#define JANUMBERLITERAL_CONSTANT_FLOAT(n) \
        ({ static const struct { const struct objc_class *isa; double value; } \
        object = { &#038;JAFloatLiteralClassObject, (n) }; \
        (NSNumber *)&object; })</pre>
<p>A problem here is that, despite all those <code>const</code>s, a non-const value can be used in Objective-C++. (In plain Objective-C, you get a moderately helpful warning about non-const initializers.) If you write a function that returns <code> JANUMBERLITERAL_CONSTANT_FLOAT(random());</code>, each instance will return the same object but its value will change, which is rather bad. The fix is to wrap this up in a macro that uses <code><a href="http://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/Other-Builtins.html#index-g_t_005f_005fbuiltin_005fconstant_005fp-2458">__builtin_constant_p()</a></code> to ensure constant objects are only created with constant values. For non-constant values, normal autoreleased <code>NSNumber</code>s are created instead.</p>
<h2>Results</h2>
<p>The above pieces, along with a bunch of extra preprocessor stuff to handle the distinctions between Objective-C and Objective-C++ and between integer and floating point values gives us a <code>$N(n)</code> macro which works as advertised: if given an integer constant it returns a <code>JAIntegerNumber</code>, for a floating point constant it returns a <code>JAFloatNumber</code>, and for a non-constant it returns an autoreleased <code>NSCFNumber</code>. But is it really working as intended? The following code:</p>
<pre class="objc-code">static NSNumber *GetNumber(void)
{
    return $N(42.0);
}</pre>
<p>disassembles to:</p>
<pre class="asm-code">    .const_data
    .align 2
_object.67163:
    .long   .objc_class_name_JAFloatNumber  // isa
    .long   0           // low bytes of 42.0
    .long   1078263808  // high bytes of 42.0</pre>
<p>…with the actual use of the object inlined (in an optimized build) to <code>movl $_object.67163, (%esp)</code>. The values 0 and 1078263808 correspond to the little-endian hex value of 42.0: <code>00000000 00004540</code>. In other words, this really is an object as constant data. For comparison, the <code>NSString</code> literal used in the sample code disassembles to:</p>
<pre class="asm-code">    .cstring
LC0:
    .ascii &quot;Hello, World! %@ = %li (%@)\0&quot;
    .section __DATA, __cfstring
    .align 2
LC1:
    .long   ___CFConstantStringClassReference // isa
    .long   1992  // flags
    .long   LC0   // bytes pointer
    .long   27    // length</pre>
<h2>Conclusion</h2>
<p>So there you have it: fully-functional, constant <code>NSNumber</code> objects, as long as you don’t use the 64-bit runtime. Now don’t go actually using it, or I’ll have to shoot your kneecaps off and leave you to Greg.</p>
<p>Oh yeah, the code is <a href="http://code.google.com/p/ahruman/source/browse/#svn/trunk/Stupid/NumberLiteral">on Google Code</a>. For a much simpler macro that just gives you an <code>NSNumber</code>, automatically choosing between integer and floating-point representations, try <a href="http://www.extinguishedscholar.com/wpglob/?p=346">natevw’s</a>.</p>
<hr />
<p><small><sup><a href="#objc-constant-objects-footnote-ref-1" name="objc-constant-objects-footnote-1">^1</a></sup></small> Its value, on my system, is 0xa00034a0. Traditionally (pre Leopard), a value above 0xFFF would mean it’s a real Objective-C class rather than a CF type tag, but that test is no longer in the <a href="http://www.opensource.apple.com/darwinsource/10.5.5/CF-476.15/">CFLite source</a> in Leopard, so it may have changed.</p>
<p>If you declare <code>extern const Class __CFConstantStringClassReference;</code> in an Objective-C++ file, you’ll get the error “&apos;__CFConstantStringClassReference&apos; has a previous declaration as &apos;int __CFConstantStringClassReference []&apos;”. In Objective-C, you won’t be told a type, just that it was “previously declared here”, referring to the location “&lt;built-in>:0”.</p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/objc-constant-objects/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Fun with the Objective-C Runtime</title>
		<link>http://jens.ayton.se/blag/fun-with-the-objc-runtime/</link>
		<comments>http://jens.ayton.se/blag/fun-with-the-objc-runtime/#comments</comments>
		<pubDate>Sat, 29 Nov 2008 21:32:32 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/?p=41</guid>
		<description><![CDATA[Ever since Leopard came out, I’ve wanted to do something useful with resolveInstanceMethod:. The opportunity has yet to present itself. However, I have done a couple of really silly things with it, which have until now languished in obscurity in &#8230; <a href="http://jens.ayton.se/blag/fun-with-the-objc-runtime/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ever since Leopard came out, I’ve wanted to do something useful with <code>resolveInstanceMethod:</code>. The opportunity has yet to present itself. However, I have done a couple of really silly things with it, which have until now languished in obscurity in the depths of <a href="http://paste.lisp.org/">paste.lisp.org</a>. So here they are.<span id="more-41"></span><br />
<h2>Easy Dictionary</h2>
<p>This allows you to use arbitrary accessors on dictionaries, or arbitrary properties if you declare them first (no definition necessary). Example:</p>
<pre class="objc-code">@interface NSDictionary (MyProperties)
@property (retain) NSString *fruit;
@end
...
NSMutableDictionary *myDict = [NSMutableDictionary dictionary];
dict.fruit = @"apple";  // -setFruit: method is generated dynamically.</pre>
<p><a href="http://code.google.com/p/ahruman/source/browse/#svn/trunk/Stupid/EasyDictionary">Google Code</a>, <a href="http://paste.lisp.org/display/55627">original lisppaste</a></p>
<h2>Silly String</h2>
<p>This defines a new string concatenation operator, <code>:</code>. Well, almost. It allows you to append any number of strings (or arbitrary object descriptions) to a string using the following syntax:</p>
<pre class="objc-code">[@"string " : @"other string " : arbitraryObject : @" yet another string "]</pre>
<p>Unfortunately, a header is required in this case to avoid unknown selector warnings.<br />
<a href="http://code.google.com/p/ahruman/source/browse/#svn/trunk/Stupid/SillyString">Google Code</a>, <a href="http://paste.lisp.org/display/71193">original lisppaste</a></p>
<h2>Disclaimer</h2>
<p>As noted in each of the files, I don’t recommend actually using these. They’re exercises in understanding the mechanics of the language rather than actually useful utilities. In particular, if you use Easy Dictionary you’re in for a world of hurt when you try to use a property that <code>NSDictionary</code> already has, like <code>count</code>, or <code>description</code>, or <code>release</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/fun-with-the-objc-runtime/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Migratory Code</title>
		<link>http://jens.ayton.se/blag/migratory-code/</link>
		<comments>http://jens.ayton.se/blag/migratory-code/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 20:09:21 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[google code]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/?p=39</guid>
		<description><![CDATA[Of the two people I know of who have tried to get at some of my code releases in the past year, a full 50&#160;% have given up and written a new implementation from scratch because downloading and opening a &#8230; <a href="http://jens.ayton.se/blag/migratory-code/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Of the two people I know of who have tried to get at some of my code releases in the past year, a full 50&nbsp;% have given up and written a new implementation from scratch because <a href="http://laprej.blogspot.com/2008/07/k-one-more-problem.html">downloading and opening a zip file is too much work</a> (as is actually complaining to someone who can fix it). On top of that, some form of version control is good to have, and my local set-ups keep breaking when I do silly things like getting a new computer or installing a new OS. So now most of my released code lives at <a href="http://ahruman.googlecode.com/">Google Code</a>. Yay and stuff.</p>
<p>Specifically, the projects in question are:</p>
<ul>
<li><a href="/blag/glsl-uniform-bindings-for-cocoa/">GLSL Bindings Sample</a></li>
<li><a href="http://jens.ayton.se/acorn/">ImageIO Export plug-in</a> for <a href="http://www.flyingmeat.com/acorn/">Acorn</a>.</li>
<li><a href="/blag/priority-queue/">JAPriorityQueue</a></li>
<li><a href="http://jens.ayton.se/blag/property-list-extractors/">JAPropertyListAccessors</a>
<li><a href="/blag/key-to-qwerty/">KeyFromQWERTY</a></li>
<li><a href="http://jens.ayton.se/code/keynaming/">KeyNaming</a></li>
<li>S3TCDecompression</li>
<li>SCDialControl</li>
<li>SCSliderWithTextField</li>
</ul>
<p>For information about the various code bits and bobs, see <a href="http://jens.ayton.se/code/">here</a>.</p>
<p>I fully expect that the next person who tries to grab some of my code will find it to onerous to dig through the subversion repo. To that person, my message is: tough.</p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/migratory-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Key to QWERTY</title>
		<link>http://jens.ayton.se/blag/key-to-qwerty/</link>
		<comments>http://jens.ayton.se/blag/key-to-qwerty/#comments</comments>
		<pubDate>Sat, 13 Sep 2008 11:29:13 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/?p=34</guid>
		<description><![CDATA[Recently on the Twitterwebs, Peter Hosey asked for a library that takes a character and returns the corresponding virtual key code (implicitly, in the U.S. keyboard layout). The intention was to use it to specify default key bindings when binding &#8230; <a href="http://jens.ayton.se/blag/key-to-qwerty/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently on the Twitterwebs, Peter Hosey <a href="https://twitter.com/boredzo/statuses/915231478">asked</a> <a href="https://twitter.com/boredzo/statuses/915251187">for</a> a library that takes a character and returns the corresponding virtual key code (implicitly, in the U.S. keyboard layout). The intention was to use it to specify default key bindings when binding to physical keys rather than characters.</p>
<p>Now personally, I like to specify my defaults in plists, and if I was hard-coding them I’d use an enum. However, I thought of a mildly amusing implementation, so I <a href="https://github.com/Ahruman/KeyNaming/tree/master/KeyFromQWERTY/">wrote it</a> (<a href="http://opensource.org/licenses/mit-license.html">MIT/X11 license</a>). It turned out to be less interestingly ugly than I expected, but did give me an opportunity to play with <code><a href="http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Other-Builtins.html#index-g_t_005f_005fbuiltin_005fconstant_005fp-2757">__builtin_constant_p</a>()</code>. This means that (if you’re using gcc) <code>KEY_FROM_QWERTY_BODY(ex)</code>, where <code>ex</code> is a constant expression, will itself be a constant expression, and if <code>ex</code> is otherwise known at compile time to be constant (e.g. a locally-defined <code>const int</code>, which is not a constant expression in C) it will be constant-folded; in other cases, a function call will be generated.</p>
<p>Also included is code to generate the header, specifically the big <code>?:</code>-based expression that does the work, using whatever keyboard layout happens to be active. Note, however, that the current implementation only includes keys that generate a single ASCII character, and skips dead keys. It includes capital letters as aliases for their lowercase equivalents, but not other shifted keys.</p>
<p>Conveniently, I’ve also written <a href="http://jens.ayton.se/code/keynaming/" title="KeyNaming">a library</a> to get a display string for a virtual key code. That one <em>does</em> use the user’s current keyboard layout.</p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/key-to-qwerty/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hacking your Log Messages</title>
		<link>http://jens.ayton.se/blag/hacking-your-log-messages/</link>
		<comments>http://jens.ayton.se/blag/hacking-your-log-messages/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 01:33:21 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[skank]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/hacking-your-log-messages/</guid>
		<description><![CDATA[More nasty code inspired by IRC conversations, but this time aimed at the iPhone SDK – although it will work on Mac&#160;OS&#160;X as well, and on WebObjects&#160;4 for Windows&#160;NT, and probably on at least some flavours of NextStep. Simply drop this &#8230; <a href="http://jens.ayton.se/blag/hacking-your-log-messages/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://jens.ayton.se/blag/hackin-ur-crash-reportz/">More</a> nasty code inspired by IRC conversations, but this time aimed at the iPhone SDK – although it will work on Mac&nbsp;OS&nbsp;X as well, and on WebObjects&nbsp;4 for Windows&nbsp;NT, and probably on at least some flavours of NextStep. Simply drop <a href="/code/files/JANSLogHack.m">this file</a> into your project, and all <code class="objc-code">NSLog()</code> output will be redirected to <code class="objc-code">stdout</code>, using a private but <a href="http://docs.info.apple.com/article.html?artnum=70081">documented</a> Foundation function.</p>
<p>Why would you want to do that? Ahh, well, that part is covered by the iPhone SDK NDA. Lawyers, eh? It must be a pretty good reason, though, given testimonials like <a href="http://twitter.com/chockenberry/statuses/796361931">this</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/hacking-your-log-messages/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Property List Extractors</title>
		<link>http://jens.ayton.se/blag/property-list-extractors/</link>
		<comments>http://jens.ayton.se/blag/property-list-extractors/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 17:42:43 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Oolite]]></category>
		<category><![CDATA[code-reuse]]></category>
		<category><![CDATA[collections]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/property-list-extractors/</guid>
		<description><![CDATA[Continuing a theme of tearing out useful bits of functionality from Oolite, and inspired by recent Twitter exchanges with Craig Hockenberry and Rainer Brockerhoff, here’s some really boring code for you all – gruntwork that you don’t want to repeat, &#8230; <a href="http://jens.ayton.se/blag/property-list-extractors/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Continuing <a href="/blag/tags/oolite/">a theme</a> of tearing out useful bits of functionality from <a href="http://oolite.org/">Oolite</a>, and inspired by recent Twitter exchanges with <a href="http://twitter.com/ahruman/statuses/786085836">Craig Hockenberry</a> and <a href="http://twitter.com/ahruman/statuses/788799034">Rainer Brockerhoff</a>, here’s some really boring code for you all – gruntwork that you don’t want to repeat, but should probably be using.</p>
<p>Executive summary for people who don’t like rambling anecdotes: property lists and user defaults should always be type-checked, and this makes it easy.</p>
<p>Oolite is highly moddable, with <a href="http://wiki.alioth.net/index.php/OXP">over 150 expansion packs</a>. Most of them are interoperable, and typically many will be in use at once. Essentially all of these contain property lists, generally written by hand by non-programmers, often on systems without plutil or Property List Editor. As such, many contain parse errors or structural problems.</p>
<p>Previous versions of Oolite blithely ignored the imperfections of mere humans. Unparseable property lists were effectively ignored, leading to unexpected behaviour, often quite subtle. Structural errors, however, caused exceptions, most of them seemingly at random.</p>
<p>The current test releases address the syntax issues by dumping the error string from <code class="objc-code">NSPropertyListSerialization</code> and the path to the relevant file to the game’s run log. A certain amount of context-sensitive type checking is done in certain areas, such as scripting (yes, property lists are used for scripting, although that’ll be deprecated in the next stable release).</p>
<p>The most significant fix, however, has been to replace most uses of <code class="objc-code">-objectForKey:</code> and <code class="objc-code">-objectAtIndex:</code> with methods that check types and perform conversions where they make sense. In particular, strings are automatically converted to numbers and booleans where appropriate, which is needed to work with the more pleasant OpenStep plist syntax. When a plist value can’t be converted to the required type, or simply isn’t there, an appropriate default value is used. The game will no longer try to get keyed objects from an array, or find the first character of a dictionary. Instead of code like this:</p>
<pre class="objc-code">// Hope plist has correct structure.
unsigned myMagicNumber = [[[plist objectForKey:@"someArray"] objectAtIndex:3] unsignedIntValue];</pre>
<p>or more fault-tolerant code like this:</p>
<pre class="objc-code">unsigned myMagicNumber = 0;
id array = [plist objectForKey:@"someArray"];
if ([array isKindOfClass:[NSArray class]] &#038;&#038; [array count] > 3)
{
    id number = [array objectAtIndex:3];
    if ([number respondsToSelector:@selector(unsignedIntValue)])
    {
        myMagicNumber = [number unsignedIntValue];
    }
}</pre>
<p>we now have code like this:</p>
<pre class="objc-code">unsigned myMagicNumber = [[plist arrayForKey:@"someArray"] unsignedIntAtIndex:3];</pre>
<p>which will not throw an exception if <code class=objc-code">@"someArray"</code> is not an array or if the array has less than four members, but will instead return 0. It’s also shorter than the broken version. Default values other than 0 can be provided in the form <code class="objc-code">[array integerAtIndex:3 defaultValue:-1]</code> or <code class="objc-code">[dictionary unsignedShortForKey:@"value" defaultValue:14]</code>.</p>
<p>Oolite is obviously an extreme case, but many applications deal with property lists. Even more deal with <code class="objc-code">NSUserDefaults</code>, which of course is a wrapper around property lists. You may think that you know what you’re putting into user defaults and can therefore rely on it to be correctly structured, but if you’re thinking that you’re wrong. First, users <em>will</em> modify your preferences file, break it, and forget they did it. Second, your code is buggy. If you write any sort of collection to your prefs, there’s a chance that you’ll put an object of the wrong class there if the phase of the moon is unusual. If you don’t check it when you read it, this will cause an exception, and you’ll end up guiding a user through digging around in ~/Library to clean up your mess. Better to be fault-tolerant to start with.</p>
<p>So, here it is: <a href="http://code.google.com/p/ahruman/source/browse/#svn/tags/Foundational/JAPropertyListAccessors%3Fstate%3Dclosed">JAPropertyListAccessors 1.0.2</a> (<a href="http://opensource.org/licenses/mit-license.html">MIT/X11 license</a>). It provides:</p>
<ul>
<li>A non-throwing variant of <code class="objc-code">-[NSArray objectAtIndex:]</code>.</li>
<li>Functions to convert objects (NSNumber or NSString) to all standard integer types, as well as float and double, clamping the results rather than overflowing, and returning a user-specified default value if no conversion can be performed.</li>
<li>Convenience methods for accessing integers, floats, strings, arrays, dictionaries, sets, or objects of a specified class from <code class="objc-code">NSArray</code>, <code class="objc-code">NSDictionary</code> or <code class="objc-code">NSUserDefaults</code>. The following transparent conversions are performed when appropriate: <code class="objc-code">NSString</code> to numbers; <code class="objc-code">NSNumber</code> and <code class="objc-code">NSDate</code> to <code class="objc-code">NSString</code>; <code class="objc-code">NSArray</code> to <code class="objc-code">NSSet</code>.
<li>Convenience methods to set integers and floating-point values in <code class="objc-code">NSMutableArray</code>, <code class="objc-code">NSMutableDictionary</code> and <code class="objc-code">NSUserDefaults</code>.</li>
<li> Unit tests for the primitive conversion functions.</li>
<li> Compatible with 32-bit and 64-bit runtimes, and with garbage-collected and non-GC code.</li>
<li> Very little in the way of comments.</li>
<p></u></p>
<p><em>Update (version 1.0.1):</em> Default value (rather than nil) is now returned when conversion to string fails. String conversion now uses <code class="objc-code">-stringValue</code> if available.</p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/property-list-extractors/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

