Club 15CC

Objective-C ~ 15CC Code

Task Code
Objective-C Sort an NSArray of Nested Dictionaries via a Key’s Value »
NSArray *arr = @[
                 @{@"label": @"one", @"count": @{@"k": @5} },
                 @{@"label": @"two", @"count": @{@"k": @9} },
                 @{@"label": @"three", @"count": @{@"k": @1} },
                 @{@"label": @"four", @"count": @{@"k": @100} },
                 ];

NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"count.k" ascending:NO];

NSArray *arr2 = [arr sortedArrayUsingDescriptors:@[sd]];
C Doxygen Member Grouping vs Comment Sharing »
// MEMBER GROUPING
// Creates a headed section with the detailed description underneath the header
/** @name Channel-channel math ops.

      Channel-channel math ops with a bit more flexibility than the operator overloads; exception on bounds error if debug is set.

     \param ch          Source channel
     \return Reference to self for chaining
 */
//@{
...
//@}

// COMMENT SHARING
// No header but share the comment amongst all enclosed members.  Must set DISTRIBUTE_GROUP_DOC = YES in config

//@{
/** Brief description
      etc...
 */
...
//@}
Objective-C Objective-C Block Definition Syntax Master Cheatsheet » A very good reference: 
//
// TYPEDEFS
//
typedef int (^MyBlockTypeWithArgs)(int, int);
typedef int (^MySimpleBlockType)();
// Obj-C object argument/return types are ok too of course...

//
// LOCAL VARS
//
int (^multiply)(int, int) = ^int(int a, int b) { return a*b; };
int (^multiply)(int, int) = ^(int a, int b) { return a*b; };        // same as above
MyBlockTypeWithArgs multiple = ^(int a, int b) { return a*b; };
MySimpleBlockType doSomething = ^{ [self _doSomething]; }; 

//
// PROPERTIES (same as local vars)
//
@property (nonatomic, copy) int (^multiply)(int, int);
@property (nonatomic, strong) MyBlockTypeWithArgs callbackBlock;

//
// METHOD ARGUMENTS
//
@interface MyClass
- (void)doItWithBlock:(int(^)(int, int))blockTakingArgs;
- (void)doItWithBlock3:(void (^)())simpleBlock;
- (void)doItWithBlock:(MyBlockTypeWithArgs)block;
@end
Objective-C Add Ivars & Properties to an Objective-C Category via Runtime »
/// An sort-of hack (not that bad really) for adding ivars and properies to Categories 

// .h file
@interface UIView (Marshmallows)
@property (nonatomic) CGFloat rotation;
@end

// .m file
#import <objc/runtime.h>

/// Key for objc_*AssociatedObject functions
static char _rotation;

@implementation UIView (Marshmallows)

- (CGFloat)rotation
{
    // Convert from object
    NSNumber *n = objc_getAssociatedObject(self, &_rotation);
    return n.floatValue;
}

- (void)setRotation:(CGFloat)rotation
{
    CGFloat delta = rotation - _rotation;
    self.transform = CGAffineTransformMakeRotation(delta);

    // Must convert to an object for this trick to work
    objc_setAssociatedObject(self, &_rotation, @(rotation), OBJC_ASSOCIATION_COPY);
}

@end
Objective-C Objective-C Block Properties With or Without a Typedef »
@property (nonatomic, copy) void (^cbPlaybackFinished)();
@property (nonatomic, copy) void (^cbPlaybackDidOccur)(NSUInteger frame, NSTimeInterval time);

// Or if you prefer
typedef BOOL (^TesterCallbackType)();
//...
@property (nonatomic, copy) TesterCallbackType cbAllowPlaybackActionCallback;
Objective-C Passing a Variable Argument List on to Another Method »
+ (void)raise:(NSString *)name  format:(NSString *)format, ...
{
    // Get the reason formatted string
    va_list args;
    va_start(args, format);
    NSString *reason = [[NSString alloc] initWithFormat:format arguments:args];
    va_end(args);

    // Throw!
    @throw [NSException exceptionWithName:name reason:reason userInfo:userInfo];
}
Objective-C Determine the Argument Count for an Objective-C Object’s Method Selector »
SEL selector = @selector(someMethodWithObject:);

// some time later....

NSMethodSignature *sig = [target methodSignatureForSelector:selector];
if ([sig numberOfArguments] > 0) {
    [target performSelector:selector withObject:self];
} else {
    [target performSelector:selector];
}
Objective-C Use OCMock to Test Whether a Method Is or Isn’t Called »
// Setup a failing mock, ie FAIL if the method IS called.
id mockSampler = [OCMockObject partialMockForObject:samplerEngine];
[[mockSampler reject] playSampleOnAudioEngine:[OCMArg any] withInitVolume:1.0f];
[mockSampler doNoteOn:@'Fb9' withVelocity:1.0f];   // Fb9 is out of range so no note should play
[mockSampler verify];

// Setup an expectation mock, ie FAIL if the method is NOT called
mockSampler = [OCMockObject partialMockForObject:samplerEngine];
[[mockSampler expect] playSampleOnAudioEngine:[OCMArg any] withInitVolume:1.0f];
[mockSampler doNoteOn:c0 withVelocity:1.0f];
[mockSampler verify];
Objective-C Block arguments for methods in Objective-C (with & without a typedef) »
typedef NSString *(^MyBlockTypeName)(NSInteger, NSString *);

@interface MyClass

- (void)doItWithBlock:(MyBlockTypeName)block;
- (void)doItWithBlock2:(NSString *(^)(NSNumber *, double))blockTakingArgs;
- (void)doItWithBlock3:(void (^)())simpleBlock;

@end
Objective-C Block-based NSNotifications with ‘self’ without creating a circular reference (retain cycle) under ARC »
- (void)setupNotification {

    // Prevents a circular reference. Otherwise dealloc will never be called
    __weak SWAnalytics *weakSelf = self;

    [[NSNotificationCenter defaultCenter]
     addObserverForName:UIApplicationDidEnterBackgroundNotification
     object:nil
     queue:[NSOperationQueue mainQueue]
     usingBlock:^(NSNotification *n) {

        [weakSelf doSomething];

     }];
}

- dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
intermediate Obj-C safe, forward declaration for a C++ class in an Obj-C++ header file »
// Let's say you have an Obj-C++ class which needs to reference a C++ class,
// perhaps for an instance variable, and you wish to include and use this
// Obj-C++ class in a regular Obj-C class. You can't include the C++ header in the
// Obj-C++ header file as this will cause problems with the importing Obj-C class.
// This snippet is the equivalent of @class for forward defining the C++ class
// in the Obj-C++ class in a way compatible with plain old Obj-C

/// Forward definition for C++ class
struct MyCPPClass;
typedef struct MyCPPClass MyCPPClass;

@interface MyObjCPPClass {
    MyCPPClass anIvar;
}

// ...

@end