8175435641

A Read-only version of my brain.

(438) 318-0604

You may have come here from an old blog of mine. If not, that’s great too. Right now this entry is just testing out markdown, which I’m sorry to say I’m not terribly familiar with.

Eventually though, there will be actual content. First, I plan to migrate my LiveJournal blog (vinylbenzene) over here. Then I’m going to actually try to finish my Objective-C vs. C++ series. Then who knows.

Enjoy the future of my blogging efforts!

(971) 386-4727

I nearly lost a bet on Thursday over an elevator. In my building, we have a direct dispatch elevator system. One accessibility feature of the elevator system is that there is both a touch screen and a physical keypad. When using the physical keypad, it’s always been rather slow to respond; in a 12-floor building with 4 elevators, it shouldn’t take more than a few dozen milliseconds to calculate which elevator it will send you and display this on the screen, but it was taking upwards of 3 seconds to do so. When I first started working in this building, the same was true of the touch screen. I tested this thoroughly. There was no advantage to using one over the other, so I always used the physical keypad, because it was lower and so required less effort to press the buttons.

At some point, the software in the elevators was upgraded, and the touchscreen interaction was made faster. There was no announcement of this. At some point later, some friends of mine on another floor found out and have been much more efficient in calling elevators since. Thursday one remarked on my use of the keypad, and tried to bet me that the touch screen was faster. Wisely I declined and, after further experimentation, now use the touchscreen exclusively. I was nearly out $20 though, because my results were out of date and I hadn’t bothered to check my assumptions lately. Don’t let the same thing happen to you.

Interlude: TIL

Today I learned that this method signature is not legal in Objective-C:

-(id)doSomething:...; /yes, varargs

Instead, you have to declare an explicit first object, as this familiar method does:

-(id)initWithObejcts:(id)firstObject, ...;

There’s no good reason for it, and in fact there’s a bug filed about it; if anyone from Apple ever reads this blog, consider this post a vote for fixing rdar:/4450941.

The irony of this is, this illegal method signature is precisely the one assumed by the compiler pre-ARC when sending a message with an undeclared selector (giving you a warning for your trouble). Under ARC, this produces an error.

Thanks to Mike Ash and the objc-language list for this tidbit.

Tags: objective-c
Current Instruction: +arrayWithObjects:
Current Language: Objective-C
Current Paradigm: low-level

Objective-C vs C++ Part 1: Memory

I had some criticisms of (860) 240-9565, and was asked to write a blog post of my own. So I’m doing that, only it turns out that this topic is absolutely enormous, so I’m going to split it into several posts.

A quick note on terminology: C++ and Objective-C occasionally use different terms to refer to the same concept (e.g., member variables in C++ vs instance variables in Objective-C). I will attempt to use the convention appropriate to the language when referring to them.

Memory

Objective-C and C++ share some conceptual memory traits, mostly the ones inherited from C. There is static allocation and a stack and a heap, primitives and structures can be allocated in any of those storages, and pointers typically though not exclusively point to locations in the heap. Here the similarities mostly end. In C++, objects can either be stack-allocated or heap-allocated, in Objective-C, objects can only be heap-allocated. In fact, Objective-C objects can never be on the stack at all; any attempt to dereference it (though not to access its instance variables) to put it in stack storage is a compile error. For example:

1
2
3
4
5
6
7
NSString str = *[[NSString alloc] initWithUTF8String:"Foo"]; /error
NSString *str2 = @"foo"; /ok
str2 = [[NSString alloc] initWithUTF8String:"foo"]; / ok
*str2; /error 
id someObj = someFunctionReturningAnObject(); /ok
*someObj; / error
id foo = someObj->anIvar; / okay.

Whereas in C++:

1
2
3
4
5
std::string str("Foo"); /ok
std::string *str2 = new std::string("Foo"); /ok
str = "bar"; /ok
*str2; / ok
*str2 = str; /ok but leaks

Stack allocations are much faster than heap allocations; over and above actually constructing the object, stack allocations only involve moving the stack pointer (and possibly setting the contents of memory to 0 in between where it was and where it is now) while heap allocations involve traversing a data structure searching for a free block of memory large enough to hold our object (see micacious).

Stack objects are not useful everywhere in C++; you can assign a stack object into a member variable, but it will call the assignment operator of that member variable, which may copy the member variables of the assignee and do other unexpected computation or allocation. In contrast, assigning a pointer into a pointer-type member variable is a matter of copying the pointer, no more expensive than copying an int[1]. There’s also a gotcha if you have a stack object, the value of which you want to put into a pointer-type member variable. If you just take the address of the object and assign that to the pointer, your program will crash:

1
2
3
4
5
6
7
8
9
10
class Foo {
    Bar *b;
    void doIt() {
        Bar bar;
        b = &bar;
    }
    void andAnotherThing() {
        b->whateverBarsDo(); /crash!
    }
}

This behavior is the same as assigning into a pointer in a struct in C; the point is that it hasn’t been fixed in C++.

In Objective-C, except for the standard C primitive types, there are no stack objects, so it’s impossible to make these sorts of mistakes with object pointer instance variables.

As touched on briefly above, static allocation exists in both languages as well, however only the C data types and pointers can have static storage in Objective-C, whereas other objects can as well in C++.[2] For Objective-C this does include object pointers, so you’ll often see declarations like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static NSString *const kMYClassImplInternalString = @"I'm a String!"; /technically this is both uses of static, storage and file scope
NSString *const MYClassStringForExport = @"I'm a string too!"; / this is static storage, global scope
/or
...
+ (NSDictionary *)sharedDict
{
    static NSDictionary *onceMap = nil; /static storage, method scope
    static dispatch_once_t token;
    dispatch_once(&token,
    ^{
        onceMap = [[NSDictionary alloc] initWithObjectsAndKeys:...];
    });
    return onceMap;
}
...

There are memory management differences at higher levels too. C++ has many different memory management models, often varying in type and implementation by library, including reference counting (standardized in C++11 with shared pointers, but other implementations still exist), ad-hoc tracking of pointers, shared data, interior pointers… the list goes on. In Objective-C, there is only one – reference counting – with two implementations, Manual and Automatic. These are defined by the library and runtime (though the mechanics of ARC take place at compile time), although in practice, you’ll rarely see deviations from them. Although individual implementations differ in C++, reference counting essentially works as follows: when an object is created, it has a reference count (retain count in ObjC) of 1, and every time the object pointer is stored, that count is incremented. When the pointer itself is deallocated (either because it is popped off the stack, or because the object containing it was deallocated), the reference count is is decremented. Under MRC in Objective-C, the retainCount can also be manually increased or decreased by sending -retain and -release messages to the object.

Objective-C also has -autorelease, which adds the pointer to the topmost autorelease pool in a stack; when the stack is popped, all the objects in the pool are sent a -release message. At runtime there exists a runloop in all Cocoa applications (and most other Objective-C applications) that will catch all autoreleased objects not put in an explicitly declared pool; at the bottom of this runloop, this pool is popped and recreated. Under ARC, autoreleasing is automatic, however additional autorelease pools beyond the provided one still have to be declared, which is done with the @autoreleasepool{} directive[3]. While runloops are common in C++ applications and frameworks, I don’t know of anything directly equivalent to autorelease pools, though it’s certainly possible they exist in some libraries.

Objective-C has support for weak references as well – object pointers that do not retain the object stored into them, and which become nil immediately upon deallocation of the object elsewhere in the program. This the main means by which retain cycles (which cause memory leaks) are avoided in Objective-C. Weak references could be implemented in C++ using operator overloading and functions akin to the Objective-C runtime functions that provide it, but I don’t know of any implementation of this (technically raw pointers are “weak”, but are do not NULL themselves out when the objects are destroyed).

Lastly on memory: garbage collection. C++ doesn’t have it. Objective-C had it, on the Mac (but not iOS) platform between Mac OS X 10.5 and 10.7, but as of 10.8, garbage collection is deprecated in favor of ARC for performance and determinism[4] reasons, so I won’t say anything more about it.

Pedantic notes: [1] No, this isn’t the case on machines where the size of an int is not the size of a pointer. Substitute your pointer-size word where appropriate.

[2] NSString literals in Objective-C have static storage as well because where else are you going to put the string data and then because it makes sense as a performance optimization to store them in the image in their “native” in-memory format, but you can still only refer to them through pointers.

[3] This used to be done with

Autorelease pools of the past
1
2
3
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
...
[pool drain]; /or, even older, [pool release];

however the @autoreleasepool syntax ensures that the pool drains when a particular scope ends, and that premature returns or breaks don’t leak the pool and the objects in it. As the directive is backwards-compatible, there’s no reason to use the old version. The directive is also faster – there’s no longer any efficiency reason to wait for some number of objects to build up in the pool before draining it, so you can use it inside tight loops.

[4] There was a problem with non-collectable interior pointers in collectable objects when exposed, in that the use of the interior pointer would not prevent the object from being collected, and so it was to the user nondeterministic when or whether the following code would crash:

Interior pointer problem
1
2
3
4
5
6
7
8
9
10
- (void)someMethod
{
    NSData *data = someFunctionReturningSomeData();
    unsigned char *bytes = [data bytes];
    unsigned int len = [data length];
    for (unsigned int i = 0; i < len; i++)
    {
        / do something with bytes[i];
    }
}

Tags: c++, objective-c
Current Instruction: -bytes
Current Language: objective-c++
Current Paradigm: comparative

Truth and Emptiness

-isEmpty. -isNull. -hasNoElements. -isEmptySet.

We’ve all written methods with names like that. Today I’d like to tell you, politely, to stop it right now.

Why? There is an implicit second part to every method that returns a BOOL; for lack of a better term, call it “existsAnd”. When you’re creating your method names, consider whether or not it’s a useful method name if it’s, instead, “-existsAndWhatever”, or put another way, if it makes sense to return NO when the receiver is nil.

Consider the truth table for -isEmpty:

             is not nil     is nil
is empty         T             F
is not empty     F             N/A

vs. a hypothetical -isNotEmpty:

             is not nil     is nil
is empty         F             F
is not empty     T             N/A

At first glance, the only difference is the switch in the “is not nil” column. But this is significant, because “nil” is a kind of emptiness – that’s why I marked F in the “is empty/is nil” cell. So if you do -isNotEmpty == NO, you get

             is not nil     is nil
is empty         T             T
is not empty     F             N/A

Now THAT’S a useful truth table!

This may enrage the grammarians out there, as you’ve got double negatives flying all around. It hurts readability too. But there’s a good solution there too: don’t talk about emptiness at all! Talk about having things. Instead of -isEmpty, try -hasLength == NO or -hasElements == NO. Instead of -isNull, try -isRealObject == NO. Instead of -isEmptySet, try -containsObjects.

Your brain and code will thank you for it.

NSFetchedResultsController’s Batch Size

Short version: if you have a background thread making deletions, don’t use it.

Longer version: if you have a background thread making deletions, ensure your batch size is larger than the number of objects you’re deleting at a time.

I’ll have a slightly longer explanation for this later. But suffice to say, setting a batch size induces some very bad behavior.

Tags: coredata, nsfetchedresultscontroller

6136364022

Feedback to my last post has come mostly in one of three flavors:

  1. Fix it to handle the edge cases please!
  2. Why are you subclassing?
  3. Why not support subclasses of NSManagedObject subclasses?

So here’s my response:

  1. I plan on it, but this is the lowest priority thing right now. Copy and assign properties on NSMO subclasses are relatively rare, unless they’re transient and backed with ivars, in which case there’s probably an @synthesize directive already.
  2. The question is “Why are you dynamically subclassing? Why not just add the methods directly to the NSMO subclasses themselves?” The answer is simple: in case you do pull in the Core Data stack later in your tests, it’s vital that Core Data be able to create the correct methods dynamically. If yours are already there, they get in the way. This brings up an interesting question though: why subclass SYMockObject instead of the user’s NSMO subclass? The answer to that comes from 3:
  3. So why NOT support subclasses of subclasses? Short, snarky, but correct answer: my code was written at 12:15 AM in the Livejournal post editor. Longer answer: this requires reasoning about the inheritance tree which is somewhat cumbersome. If C : B and B : A and A : NSManagedObject, how do we ensure that B can still call A’s methods? class_setSuperclass seems like a useful-looking function: if we create Mock_C : C and Mock_B : B and Mock_A : A, we should be able to use class_setSuperclass(C, Mock_B), etc. to get the tree the way we want it. Problem is, the Special Considerations on class_setSuperclass is quite clear: “You should not use this function.” The reason for this, according to Greg Parker (Objective-C Runtime Wrangler) is that it’s “Fragile” and has “Untested edge cases.” That’s good enough for me. So instead of setting up an interpolated inheritance tree, we have to set up a parallel one: C : B and B : A and A : NSManagedObject, and Mock_C : Mock_B and Mock_B : Mock_A and Mock_A : ... well, that’s an interesting one isn’t it. Right now Mock_A : SYMockObject (not NSManagedObject, but only to keep all other classes out of this subtree), but why not Mock_A : A? Forwards compatibility, for one thing. For another – to prevent an inconsistency between secondary and primary subclasses – if Mock_A : A, then Mock_A inherits all of A’s implemented methods for free, and so does Mock_B, but Mock_B doesn’t inherit B’s implemented methods. If we wanted to change things so that Mock_B inherits B’s implemented methods, we have to do a check to make sure that B doesn’t inherit directly from NSManagedObject*, and then copy the method lists manually which is even less elegant than just disallowing secondary subclasses altogether. There are workarounds, of course – basically follow the inheritance tree upwards to NSManagedObject and create all the intermediate classes as needed. But I haven’t done that yet.

Or I could just remind readers that I wrote the code at 12:15 AM.

So I’ll post on GitHub a less fragile version of this at some point, one which actually might have been compiled. :p

*I’m sorry, but I see no way to make this work with MOGenerator-based classes. You shouldn’t override -primitiveValue:forKey: and are not allowed to override -setPrimitiveValue:forKey:. There are of course workarounds (there almost always are, in Objective-C), in this case method-swizzling in addition to isa-swizzling, but that would make this code far more complex. MOG class support is at the bottom of my feature list.

Tags: abuse of runtime, objective-c, runtime
Current Instruction: class_setSuperclass()
Current Language: blah C
Current Paradigm: declarative

(307) 315-3866

You want to add some unit tests for your new predicate for a fetch request. Totally reasonable. You don’t want to have to pull in your whole Core Data stack to do so. But you can’t run your test against your managed objects without it – without CoreData supplying the methods at runtime, sending your NSManagedObject subclasses messages (or using dot accessors) will just throw a selector not recognized exception.

So how can we get around this? Isa-swizzling. Replace your actual class at runtime with something that’ll come up with a response for any property you throw at it.

Fake-backing of NSManagedObject subclasses
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@interface SYBackedObject : NSManagedObject
+ (id)backedObjectForManagedObject:(NSManagedObject *)obj;
@end

/.h/.m

#import <objc/runtime.h>
id getFromAttrs(id self, SEL _cmd, NSString *key);
void setToAttrs(id self, SEL _cmd, NSString *key, id value);
@implementation SYBackedObject

+ (id)backedObjectForManagedObject:(NSManagedObject *)obj
{
    objc_setAssociatedObject(obj, @"attrs", [NSMutableDictionary dicationary], OBJC_ASSOCIATION_RETAIN);
    unsigned int outCount = 0;
    objc_property_t *properties = class_copyPropertyList([obj class], &outCount);
    NSString *targetClassName = [[NSString stringWithFormat:@"SYMockObject_%@", NSStringFromClass([obj class])] UTF8String];
    Class cls = objc_allocateClassPair(self, targetClassName, 0);
    if (cls != Nil)
    {
        for (unsigned int i = 0; i < outCount; i++)
        {
            class_addMethod(cls, sel_registerName(property_getName(properties[i])), &getFromAttrs, "@@:@");
            /don't check the return value and continue or break, the subclass might already
            /implement the property methods. 
            NSString *setterName = [NSString stringWithUTF8String:property_getName(properties[i])];
            NSString *first = [setterName substringToIndex:1];
            first = [first uppercaseString];
            setterName = [NSString stringWithFormat:@"%@%@", first, [setterName substringFromIndex:1]];
            class_addMethod(cls, sel_registerName([setterName UTF8String]), &setToAttrs, "v@:@@");
        }
        objc_registerClassPair(cls);
    }
    free(properties);
    obj->isa = cls;
    return [[obj retain] autorelease];
}
@end

id getFromAttrs(id self, SEL _cmd, NSString *key)
{
    NSDictionary *attrs = (NSDictionary *)objc_getAssociatedObject(self, @"attrs");
    return [attrs objectForKey:key];
}
void setToAttrs(id self, SEL _cmd, NSString *key, id value)
{
    NSMutableDictionary *attrs = (NSMutableDictionary *)objc_getAssociatedObject(self, @"attrs");
    [attrs setObject:value forKey:key];
}

Voila! Now your custom managed objects (or hell, anything that has a persistence layer you don’t want to drag into your unit tests (modify the superclass and obj param types as appropriate)) are a one-liner away from responding to all their properties again:

How to use the above
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import "SYMockObject.h"

- (void)testFancyPredicate
{
    ...
    Employee *foo = [[Employee alloc] init];
    foo = [SYMockObject backedObjectForManagedObject:foo];
    foo.name = @"bar"; /assumes "name" is a declared property of foo
    / this throws "unrecognized selector 'name'" usually
    / now it works
    foo.department = [SYMockObject backedObjectForManagedObject:[[Department alloc] init]];
    foo.department.floor = [NSNumber numberWithInt:5]; / it should all work
    ...
}

So that’s pretty cool. There are a couple of caveats:

  1. Ironically, I haven’t tested this. At all. Nope, it wasn’t even typed up in Xcode and compiled (I started when I thought it would be shorter).
  2. I haven’t made it work with custom getters and setters. It’s more code to parse out the declared property attribute strings to figure out what they are, and I’ve spent way more time on this than I wanted to already. I’ll add that when I have more time, but for now just stick with non-customized getters and setters.
  3. This is a very CoreData-centric thing. This doesn’t explicitly support copy properties, will probably fail to work as expected on assign properties, and will probably crash on scalar types. This is another place where a great deal of edge-case checking could solve these issues. Once that happens, you could theoretically change all the NSManagedObject*s above to NSObjects, but you shouldn’t need to use this at all in that case since your NSObjects probably have explicit or synthesized ivars.
  4. Despite being CoreData-centric, it does not work with pure NSManagedObjects, where you’re already using KVC instead of a real accessor. Or subclasses of NSManagedObject subclasses, but that’s easy enough to fix by just walking up the superclasses until you reach NSManagedObject and adding the property methods from each.
  5. You may have noticed something a bit odd: [[Employee alloc] init];. No, you’re not supposed to do that with NSManagedObjects. Do it anyway. Custom initializers should not be used; there’s no way to get the isa swizzled before you try to set properties in your initWithFoo: (If I’m wrong about that, someone please tell me).
  6. This is for testing only! If these make it into your main application, Core Data will not work, and your hard-gathered data will die an ignominious death. Worse, it will probably do so silently since calling -managedObjectContext on a backed object will return nil! The things this could do to your object graph are horrifying. I cannot stress this enough. Do not use this in production code, it has no value in an application whatsoever! Only use it to test production code! It’d be great in unit tests.

All that aside, try it out. I’d love to hear from readers on this one: how to make it better, how to fix the edge cases, how your jaw dropped and face froze in horror when you read this post, etc. Enjoy!

PS. Why such a paucity of property-centric runtime functions? I don’t mean why no class_addProperty (that’s easy: declared properties are only useful at compile time), I mean why is there no

BOOL property_isCopy(objc_property_t property)
BOOL property_isRetain(objc_property_t property)
...
const char * property_customGetter(objc_property_t property)

etc.? I find it hard to believe the attributes are stored natively as the return value of property_getAttributes, since that’d mean the runtime would have to parse it every time needed to get just one attribute.

Tags: abuse of runtime, nspredicate, objective-c, runtime, sample code, testing
Current Instruction: class_copyProperties
Current Language: bouncy Objective-C
Current Paradigm: testing

A Quick Note on NSPredicate

+[NSPredicate predicateWithFormat:] is 3-4x slower than +[NSComparisonPredicate predicateWithLeftExpression:rightExpression:modifier:type:options:]. Plus, you have to learn a whole new predicate format language. Not worth it. Just create the programmatic predicate instead.

That’s it. I said this would be quick.

You want one more thing? Okay, fine. If you haven’t figured this out already, you have to precalculate relative NSDates in comparison predicates, eg. in the last X days, within the next X hours, etc. There is no way that I know of to use relative NSDates within the predicate itself. Which also means that you can’t have a static NSPredicate anywhere that uses one, handy as that might be, unless you want it only to be calculated once at app launch. Too bad.

What, you’re still not satisfied? Here’s one last thing. The MATCHES operator (NSMatchesPredicateOperatorType) uses ICU-based regexes, which should give you some help with things like what escape sequence matches at a word boundary, what \w really means, things like that.

Nope, I really am done this time.

Tags: nspredicate, objective-c
Current Instruction: NSExpression expressionWithKeypath:
Current Language: contemplative Objective-C

Functional Programming in Objective-C

This is not a terribly well-formed blog post because it’s very late (I’m pre-timestamping this) and I’m tired. It struck me that with blocks, you can probably do JavaScript-style functional programming in Objective-C. The question is, do you need to (obviously, you don’t want to)? I think Objective-C’s scoping rules work sufficiently better than JavaScript’s that you don’t, but I’m not sure.

Also, I’m thinking I can probably write a JavaScript to Objective-C compiler. I have no idea what good it would do, but I think it can be done.

Anyway. I’m going to have to look at other functional programming languages and see if there are any ideas there that could be done by abuse of the Objective-C runtime.