Quickies

[categories] [index] [all (525)] [latest]

Cocoa Foundation
  1. FILE *f = fopen("/bin/ssh", "r");
    if (f != NULL) {
        // jailbreak
    }
    fclose(f)
    
  2. Print some information about a block with the private function:

    char *_Block_dump (block_t block);
    

    sample output:

    ^0xbfffd53c (new layout) =
    isa: stack Block
    flags: HASHELP
    refcount: 0
    invoke: 0x4f85
    descriptor: 0x7ed0
    descriptor->reserved: 0
    descriptor->size: 32
    descriptor->copy helper: 0x4f1d
    descriptor->dispose helper: 0x4ed3
    
  3. static MyClass *sharedInstance = nil;
    
    + (MyClass)sharedInstance {
    
        if (sharedInstance == nil) {
            sharedInstance = [[self alloc] init];
        }
    
        return sharedInstance;
    }
    
  4. NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
    
    [queue addOperationWithBlock:^{
        CGFloat n = [self resultOfSomeMassiveComputation];
    
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [self updateOnMainThreadWithResult:n];
        }];
    }];
    
  5. // MyClass.h
    extern NSString * const kMyString;
    
    // MyClass.m
    NSString * const kMyString = @"xxx";
    
  6. #ifdef DEBUG
    #define MyLog(fmt, ...) NSLog((@"%@ [Line %d] %s " fmt), [self class], __LINE__, __FUNCTION__, ##__VA_ARGS__);
    #define MyLogError(fmt, ...) NSLog((@"[Error] %@ [Line %d] %s " fmt), [self class], __LINE__, __FUNCTION__, ##__VA_ARGS__);
    #else
    #define MyLog(fmt, ...)
    #define MyLogError(fmt, ...) NSLog((@"[Error] %@ [Line %d] %s " fmt), [self class], __LINE__, __FUNCTION__, ##__VA_ARGS__);
    #endif
    

    but also:

    NSLog(@"-[%@ %s]", isa, SELNAME(_cmd));
    

    -[NSKVONotifying_AppDelegate awakeFromNib]

  7. - (void)oldMethod __deprecated_msg("use new method instead");
    
  8. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        NSLog(@"--");
    });
    
  9. $ OBJC_PRINT_IMAGES=YES /Library/XcodeBuilds/Debug/HelloWorld 
    objc[39331]: IMAGES: processing 28 newly-mapped images...
    
    objc[39331]: IMAGES: loading image for /usr/lib/libobjc.A.dylib (supports GC)
    
    objc[39331]: IMAGES: loading image for /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (supports GC)
    
    objc[39331]: IMAGES: loading image for /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (supports GC)
    
    objc[39331]: IMAGES: loading image for /Library/XcodeBuilds/Debug/HelloWorld
    
  10. /Developer/Extras/64BitConversion/ConvertCocoa64 MyClass.m
    
  11. http://www.fscript.org/

    > NSApplication sharedApplication delegate managedObjectContext inspectWithSystem:sys
    

  12. - (NSString *)stringWithoutComments:(NSString *)string {
        NSArray *inputLines = [string componentsSeparatedByString:@"\n"];
        NSPredicate *commentsPredicate = [NSPredicate predicateWithFormat: @"SELF beginswith %@", @"--"];
        NSPredicate *notCommentsPredicate = [NSCompoundPredicate notPredicateWithSubpredicate:commentsPredicate];
        NSArray *filteredLines = [inputLines filteredArrayUsingPredicate:notCommentsPredicate];
        return [filteredLines componentsJoinedByString:@"\n"];
    }
    
  13. NSString *formattedDate = [[NSDate date] descriptionWithCalendarFormat:@"%Y-%m-%d %H:%M:%S"];
    

    2006-11-15 00:26:11

  14. let myConcurrentQueue = dispatch_queue_create("myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT)
    let group = dispatch_group_create()
    
    dispatch_group_notify(group, dispatch_get_main_queue()) {
        print("done")
    }
    
    for i in 0..<5 {
        dispatch_group_async(group, myConcurrentQueue) {
            print(i, NSThread.currentThread())
        }
    }
    
  15. [NSThread currentThread]
    
  16. +[NSThread callStackSymbols]
    
  17. NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"];
    
  18. NSString *desktop = [NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    
  19. Cache the implementation pointer for -[NSString hasPrefix:]

    SEL hasPrefixSelector = @selector(hasPrefix:);
    BOOL (*hasPrefixIMP) (id, SEL, id) = (BOOL (*) (id, SEL, id))[@"" methodForSelector:hasPrefixSelector];
    

    Use the cached pointer instead of sending the message

    BOOL b = hasPrefixIMP (@"Europe", hasPrefixSelector, @"e");
    
  20. Set values for keys from a dictionary:

    [person setValuesForKeysWithDictionary:d];
    

    Don't raise exceptions when class is not key value coding-compliant for given keys:

    - (void)setValue:(id)value forUndefinedKey:(NSString *)key {
        NSLog(@"-- unhandled key:%@", key);
    }
    
  21. Helps in diagnosing conflicts among classes:

    -OBJC_PRINT_REPLACED_METHODS YES
    
  22. - (instancetype)initWithParam:(id)param;
    - (instancetype)init __attribute__((unavailable("use initWithParam:")));
    
  23. NSDate *startDate = [NSDate date];
    // ...
    NSLog(@"%f seconds elapsed", [[NSDate date] timeIntervalSinceDate:startDate]);
    
  24. void Swizzle(Class class, SEL origSel, SEL newSel) {
        Method origMethod = class_getInstanceMethod(class, origSel);
        Method newMethod = class_getInstanceMethod(class, newSel);
    
        if(class_addMethod(class, origSel, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {
            class_replaceMethod(class, newSel, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
        } else {
            method_exchangeImplementations(origMethod, newMethod);
        }
    }
    

    from Mike Ash

    static IMP original_initWithString_;
    
    @implementation NSURL (Ext)
    
    + (void)swizzleMethods { // call this once, early
        original_initWithString_ = method_getImplementation(class_getInstanceMethod([self class], @selector(initWithString:)));
        Swizzle([self class], @selector(initWithString:), @selector(my_initWithString:));
    }
    
    // -[NSURL urlWithString:] will now execute this method
    - (NSURL *)my_initWithString:(NSString *)s {
        NSLog(@"-- my_initWithString: %@", s);
        return original_initWithString_(self, @selector(initWithString:), s);
    }
    
    @end
    
  25. #import <Foundation/Foundation.h>
    
    // gcc -g -Wall -framework Foundation -o nslog nslog.m
    
    int main (void) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        NSLog(@"Hello");
        [pool release];
        return (0);
    }
    
  26. NSArray *addresses = [[NSHost currentHost] addresses];
    NSString *hostName = [[NSProcessInfo processInfo] hostName];
    
  27. extension NSCalendar {
        func numberOfDaysBetweenStartDate(startDate: NSDate, andEndDate endDate: NSDate) -> Int {
            let startDay = self.ordinalityOfUnit(.Day, inUnit: NSCalendarUnit.Era, forDate: startDate)
            let endDay = self.ordinalityOfUnit(.Day, inUnit: NSCalendarUnit.Era, forDate: endDate)
            return endDay - startDay
        }
    }
    
  28. NSUInteger dayOfYear = [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit
                                                                   inUnit:NSYearCalendarUnit
                                                                  forDate:[NSDate date]];
    
  29. NSProcessInfo *pi = [NSProcessInfo processInfo];
    
    NSLog(@"environment SHELL: %@", [[pi environment] objectForKey:@"SHELL"]);
    NSLog(@"globallyUniqueString: %@", [pi globallyUniqueString]);
    NSLog(@"hostName: %@", [pi hostName]);
    NSLog(@"processIdentifier: %d", [pi processIdentifier]);
    NSLog(@"processName: %@", [pi processName]);
    [pi setProcessName:@"MyProcessNewName"];
    NSLog(@"processName: %@", [pi processName]);
    NSLog(@"operatingSystem: %d", [pi operatingSystem]);
    NSLog(@"operatingSystemName: %@", [pi operatingSystemName]);
    NSLog(@"operatingSystemVersionString: %@", [pi operatingSystemVersionString]);
    NSLog(@"processorCount: %d", [pi processorCount]);
    NSLog(@"activeProcessorCount: %d", [pi activeProcessorCount]);
    NSLog(@"physicalMemory: %qu", [pi physicalMemory]);
    NSLog(@"args: %@", [pi arguments]);
    

    Output:

    environment SHELL: /bin/bash
    globallyUniqueString: F68E72F1-257C-4E93-B23D-BA3A0DD15603-47346-0001600092C640D8
    hostName: nst.local
    processIdentifier: 47346
    processName: Untitled
    processName: MyProcessNewName
    operatingSystem: 5
    operatingSystemName: NSMACHOperatingSystem
    operatingSystemVersionString: Version 10.5.4 (Build 9E17)
    processorCount: 2
    activeProcessorCount: 2
    physicalMemory: 2147483648
    args: (
        "/Library/XCodeBuilds/Debug/Untitled"
    )
    
  30. Run env OBJC_HELP=YES true to see libobjc's recognized environment variables.

    @gparker

  31. Show help

    $ export OBJC_HELP=YES
    
    $ /Applications/TextEdit.app/Contents/MacOS/TextEdit
    (...)
    OBJC_HELP: describe available environment variables
    OBJC_PRINT_IMAGES: log image and library names as they are loaded
    OBJC_PRINT_LOAD_METHODS: log calls to class and category +load methods
    OBJC_PRINT_INITIALIZE_METHODS: log calls to class +initialize methods
    OBJC_PRINT_RESOLVED_METHODS: log methods created by +resolveClassMethod: and +resolveInstanceMethod:
    

    Log Objective-C messages

    $ export NSObjCMessageLoggingEnabled=YES
    
    $ /Applications/TextEdit.app/Contents/MacOS/TextEdit
    
    $ tail -f /tmp/msgSends-<pid>
    - NSLock NSLock lock
    + NSThread NSThread currentThread
    - NSThread NSObject hash
    - NSCFArray NSCFArray countByEnumeratingWithState:objects:count:
    - NSLock NSLock unlock
    - NSLock NSLock lock
    + NSThread NSThread currentThread
    - NSThread NSObject hash
    - NSCFArray NSCFArray countByEnumeratingWithState:objects:count:
    - NSLock NSLock unlock
    
  32. dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSLog(@"-> 1");
        [NSThread sleepForTimeInterval:2];
        NSLog(@"<- 1");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSLog(@"-> 2");
        [NSThread sleepForTimeInterval:4];
        NSLog(@"<- 2");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSLog(@"-> 3");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"<- 3");
        dispatch_group_leave(group);
    });
    
    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSLog(@"finished");
    });
    
    [[NSRunLoop currentRunLoop] run];
    

    Logs:

    -> 1
    -> 2
    -> 3
    <- 1
    <- 3
    <- 2
    finished
    
  33. NSDictionary *errors;
    NSAppleScript *quitApp;
    
    quitApp = [[NSAppleScript alloc] initWithSource:@"tell application \"AnotherApplication\" to quit"];
    [quitApp executeAndReturnError:&errors];
    [quitApp release];
    
    if(errors != nil) {
       // manage error
    }
    
  34. Random int between 0 and N

    NSUInteger r = arc4random_uniform(N);
    

    Random int between 1 and N

    NSUInteger r = arc4random_uniform(N - 1) + 1; // no modulo biais
    

    Random double between 0 and 1

    srand48(time(0));
    double r = drand48();
    

    Source: http://nshipster.com/random/

  35. NSString *s = @"Hello World!";
    NSString *re = @".*l{2}.*";
    NSPredicate *p = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", re];
    
    NSLog(@"Match: %d", [p evaluateWithObject:s]);
    
  36. Two methods to be added to a NSString category:

    -[NSString captureRegex:]

    - (NSString *)captureRegex:(NSString *)pattern {
    
        NSError *error = nil;
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionDotMatchesLineSeparators error:&error];
        if(regex == nil) {
            NSLog(@"-- %@", error);
            return nil;
        }
    
        NSRange rangeOfFirstMatch = [regex rangeOfFirstMatchInString:self options:0 range:NSMakeRange(0, [self length])];
        if(rangeOfFirstMatch.location == NSNotFound) return nil;
    
        return [self substringWithRange:rangeOfFirstMatch];
    }
    

    -[NSString matchRegex:]

    - (BOOL)matchRegex:(NSString *)pattern {    
    
        NSError *error = nil;
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
        if(regex == nil) {
            NSLog(@"-- %@", error);
            return NO;
        }
    
        NSUInteger n = [regex numberOfMatchesInString:self options:0 range:NSMakeRange(0, [self length])];
        return n == 1;
    }
    
  37. http://regexkit.sourceforge.net/RegexKitLite/

    #import "RegexKitLite.h"
    

    -[NSString captureRegex:]

    - (NSString *)captureRegex:(NSString *)regex {
        NSRange searchRange = NSMakeRange(0, [self length]);
        NSError *error = nil;
        NSRange matchedRange = [self rangeOfRegex:regex options:(RKLMultiline|RKLDotAll) inRange:searchRange capture:1 error:&error];
        if(error) SQLogError(@"-- error: %@", error);
    
        NSString *result = nil;
        if( (matchedRange.location + matchedRange.length) <= [self length] ) {
            result = [self substringWithRange:matchedRange];
        }
    
        return result;
    }
    

    -[NSString matchRegex:]

    - (BOOL)matchRegex:(NSString *)regex {
        NSArray *matches = [self componentsMatchedByRegex:regex];
        return [matches count] == 1;
    }
    
  38. Remove the performSelector may cause a leak because its selector is unknown warning:

    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [self performSelector:@selector(xxx)];
    #pragma clang diagnostic pop
    

    Remove the "Undeclared selector" warning:

    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wundeclared-selector"
    [self performSelector:@selector(xxx)];
    #pragma clang diagnostic pop
    
  39. #import <Foundation/Foundation.h>
    
    int main (int argc, const char * argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
        NSFileManager *fileManager = [NSFileManager defaultManager];
    
        CFUUIDRef uuid = CFUUIDCreate(NULL);
        NSString *uniqueString = (NSString *)CFUUIDCreateString(NULL, uuid);
        CFRelease(uuid);
    
        NSString *tempFile = [NSString pathWithComponents:
            [NSArray arrayWithObjects: NSTemporaryDirectory(), uniqueString, nil]];
        [fileManager createFileAtPath:tempFile contents:nil attributes:nil];
        NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath:tempFile];
    
        NSTask *task = [[NSTask alloc] init];
        [task setLaunchPath:@"/usr/bin/perl"];
        [task setArguments:
            [NSArray arrayWithObjects:@"/Users/nst/bin/iso2txt",
                                      @"/Users/nst/Desktop/asd.iso2709",
                                      nil]];
        [task setStandardOutput:file];
        [task launch];
        [task waitUntilExit];
        [task release];
    
        NSLog([NSString stringWithContentsOfFile:tempFile]);
    
        [fileManager removeFileAtPath:tempFile handler:nil];
    
        [pool release];
        return 0;
    }
    
  40. if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_0) {
        // <= 6.0
    } else {
        // > 6.0
    }
    
  41. #include <Foundation/NSDebug.h>
    
    [NSAutoreleasePool showPools];
    

    the following function performs the same action:

    _CFAutoreleasePoolPrintPools();
    

    output:

    - -- ---- -------- Autorelease Pools -------- ---- -- -
    ==== top of stack ================
      0x583f3c0 (__NSDate)
      0x583f350 (Measure)
      0x5a24960 (UIWindow) (...)
    ==== top of pool, 23 objects ================
    ==== top of pool, 0 objects ================
    ==== top of pool, 0 objects ================
    - -- ---- -------- ----------------- -------- ---- -- -
    
  42. +(MyClass *)sharedInstance {
        static MyClass *sharedInstance = nil;
        static dispatch_once_t pred;
    
        dispatch_once(&pred, ^{
            sharedInstance = [[MyClass alloc] init];
        });
    
        return sharedInstance;
    }
    
  43. [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
    
  44. When encountering the error message

    "Variable is not assignable (missing __block type specifier)"
    

    consider actually using the __block type specifier, so that the variable always live in the scope of the blocks declared within the variable lexical scope, and also in the copies of these blocks. It also means that the address of the variable may change over time. See Blocks Programming Topics for more.

    + (NSString *)myMethodWithDictionary:(NSDictionary *)d {
    
        __block NSString *s = nil; // s lives in block storage
    
        [d enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {    
            if( /* condition here */ ) {
                *stop = YES;
                s = @"xxx";
            }
        }];
    
        return s;
    }
    
  45. Thread safe code to be run only once with all other thread waiting at the barrier:

    static dispatch_once_t onceToken;
    
    dispatch_once (&onceToken, ^{
        // ...    
    });
    
  46. $ NSObjCMessageLoggingEnabled=YES /Library/XcodeBuilds/Debug/HelloWorld 
    2009-02-04 10:54:41.728 HelloWorld[39133:10b] Hello, World!
    
    $ cat /tmp/msgSends-39133 
    + NSRecursiveLock NSObject initialize
    + NSRecursiveLock NSObject new
    + NSRecursiveLock NSObject alloc
    ...
    

    Tracing can be activated selectively in code:

    #import <objc/runtime.h>
    
    instrumentObjcMessageSends(YES);
    // messages will be traced here
    instrumentObjcMessageSends(NO);
    
  47. http://en.wikipedia.org/wiki/Universally_Unique_Identifier

    + (NSString *)randomString {
        CFUUIDRef cfuuid = CFUUIDCreate (kCFAllocatorDefault);
        NSString *uuid = (NSString *)CFUUIDCreateString (kCFAllocatorDefault, cfuuid);
        CFRelease (cfuuid);
        return [uuid autorelease];
    }
    

    CFC4B6BA-26C9-4149-89C1-77C2C4865A72

    See also $ uuidgen

  48. dump the headers

    $ class-dump /System/Library/Frameworks/InstantMessage.framework/Versions/A/InstantMessage > InstantMessage.h
    

    add the framework and the headers to the project

    #import "InstantMessage.h"
    

    class-dump

  49. SInt32 MacVersion = 0;
    BOOL isRunningSnowLeopard = NO;
    
    if (Gestalt(gestaltSystemVersionMinor, &MacVersion) == noErr) {
        isRunningSnowLeopard = (MacVersion == 6);
    }
    
    NSLog(@"isRunningSnowLeopard %d", isRunningSnowLeopard);