5
\$\begingroup\$

I wanted to store CMTimeRange structures inside managed objects, so I've worked out the following:

@interface Clip : NSManagedObject

@property (nonatomic, retain) NSData * primitiveRange;
@property CMTimeRange range;

@end

Within the data model editor I've set the type of primitiveRange to "Transformable".

The implementation:

@implementation Clip
{
    CMTimeRange _range;
}
@dynamic primitiveRange;

// pre-calculated get    
- (void)awakeFromFetch
{
    [super awakeFromFetch];

    NSData *data = [self primitiveValueForKey:@"primitiveRange"];
    if (data) {
        _range = CMTimeRangeMakeFromDictionary((__bridge CFDictionaryRef)[NSKeyedUnarchiver unarchiveObjectWithData:data]);
    }
}

- (CMTimeRange)range
{
    [self willAccessValueForKey:@"primitiveRange"];
    CMTimeRange value = _range;
    [self didAccessValueForKey:@"primitiveRange"];

    return value;
}

// immediate-update set
- (void)setRange:(CMTimeRange)range
{
    NSData *value = [NSKeyedArchiver archivedDataWithRootObject:CFBridgingRelease(CMTimeRangeCopyAsDictionary(range, kCFAllocatorDefault))];

    [self willChangeValueForKey:@"primitiveRange"];
    [self setPrimitiveValue:value forKey:@"primitiveRange"];
    [self didChangeValueForKey:@"primitiveRange"];

    _range = range;
}

This works fine, but is this the proper way of doing things?

\$\endgroup\$
2
\$\begingroup\$

Objective-C doesn't have namespaces. As such, we need to be much more careful with our class names. The common way for dealing with this problem in Objective-C is to come up with a 2 or 3 letter prefix to put in front of all of your classes. Apple does this with their classes.

  • NS for NeXTSTEP
  • CF for CoreFoundation
  • UI for UserInterface
  • SK for SpriteKit
  • CM for CoreMotion (but I think it overlaps something else maybe)
  • CA for CoreAnimation
  • CG for CoreGraphics

And there are more.

If it weren't for this naming convention, Apple would have a hard time creating class like NSView for OS X development and UIView for iOS development.

Following in this path, other good Objective-C developers come up with their own acronyms to prefix their various classes, structs, and typealiases with. And you should do the same. Clip just will not work as a class name (plus, it's not particularly expressive of what the class actually represents... is this like a movie clip or audio clip or something?).


I believe most Objective-C programmers prefer Egyptian braces. You're consistent-ish with your braces though, that's fine-ish and not a necessary change. I say consistent-ish because you use Egyptian braces for your if, but not for your methods. Due to the way Xcode folds code, I consider Egyptian style to be vastly superior if you're developing in Xcode.


Finally... we often talk about (especially in Code Reviews), magic numbers. You don't have any of these, but I'm going to go ahead and call @"primitiveRange" a magic string.

We should define a constant, and perhaps use reverse domain lookup for your keys:

NSString * const kKEY_PrimitiveRange = @"com.yourDomain.clip.primitiveRange";

Your using this string in 6 places. What happens if, for whatever reason, you decide to change the string? Now you have to change it in 6 different places. If we'd just use a string constant, if we ever change the string, we only have to change it in one place.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.