strong/weak ptr in ARC and C++11

__strong / __weak in ARC vs shared_ptr / weak_ptr in C++11.

result

*** ARC ***
I'm CocoaPitcher, ball = <CocoaBall: 0x7f8809d00570>
I'm CocoaPitcher, ball = (null)
*** C++11 ***
I'm CppPitcher, ball = 7802300.
I'm CppPitcher, ball is null.

main.mm

#import <Foundation/Foundation.h>
#import "CocoaPitcher.h"
#import "CocoaBall.h"
#include "CppPitcher.h"
#include "CppBall.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        NSLog(@"*** ARC ***");
        CocoaPitcher *pitcher = [[CocoaPitcher alloc] init];

        @autoreleasepool {
            CocoaBall *ball = [[CocoaBall alloc] init];
            pitcher.ball = ball;
            [pitcher print];                
        }
        [pitcher print];
        
        NSLog(@"*** C++11 ***");
        std::shared_ptr<CppPitcher> cppPitcher(new CppPitcher);
        {
            std::shared_ptr<CppBall> ball(new CppBall);
            cppPitcher->ball = ball;
            cppPitcher->print();
        }
        cppPitcher->print();
    }
    return 0;
}

CocoaPitcher.h/m

#import <Foundation/Foundation.h>

@class CocoaBall;

@interface CocoaPitcher : NSObject

- (void)print;

@property (weak) CocoaBall *ball;

@end

#import "CocoaPitcher.h"
#import "CocoaBall.h"


@implementation CocoaPitcher
@synthesize ball;

- (void)print {
    NSLog(@"I'm %@, ball = %@", [self class], ball);
}
@end

CppPitcher.h/cpp

#include <memory>

class CppBall;

class CppPitcher {
public:
    void print();
    std::weak_ptr<CppBall> ball;
};

#include "CppPitcher.h"
#include "CppBall.h"

void CppPitcher::print(){
    printf("I'm CppPitcher, ");
    if (auto b = ball.lock()) {
        printf("ball = %x.\n", b.get());
    } else {
        printf("ball is null.\n");
    }
}

Ramdisk backup & restore on MacOS X Lion

rd-backup.sh:

#!/bin/sh

mount |grep /Volumes/RamDisk > /dev/null
if [ $? -eq 0 ]; then
    echo saving /Volumes/RamDisk in /var/spool/rdimage
    sudo rsync -av --delete /Volumes/RamDisk/ /var/spool/rdimage/
    sudo diskutil unmount /Volumes/RamDisk
fi

rd-restore.sh:

#!/bin/sh

mount |grep /Volumes/RamDisk > /dev/null
if [ $? -ne 0 ]; then
    # 2GB
    sudo diskutil erasevolume HFS+ "RamDisk" `hdiutil attach -owners on -nomount ram://4194304`
    sudo diskutil enableOwnership /Volumes/RamDisk

    #restore ramdisk image from disk
    sudo rsync -a /var/spool/rdimage/ /Volumes/RamDisk/
fi

And use it as a temporary area in Xcode etc.

Automatic Reference Counting

Tested __strong, __weak and __unsafe_unretained.
__weak reference becomes nil when the target is dealloced, __unsafe_unretained becomes a dangling pointer.

Test Result:
1. Alloc -> Print

2012-06-14 23:49:08.286 ArcSpike[1561:403] strong: <NSObject: 0x7f8813b225c0>
2012-06-14 23:49:08.287 ArcSpike[1561:403] weak:   <NSObject: 0x7f8813b225c0>
2012-06-14 23:49:08.287 ArcSpike[1561:403] unsafe: <NSObject: 0x7f8813b225c0>

2. Alloc -> Free -> Print

2012-06-14 23:49:09.253 ArcSpike[1561:403] strong: (null)
2012-06-14 23:49:09.254 ArcSpike[1561:403] weak:   (null)
2012-06-14 23:49:09.255 ArcSpike[1561:403] unsafe: <NSObject: 0x7f8813b225c0>

or, causes access violation when referencing unsafeReference in print.

Test Code:

@interface WindowController : NSWindowController
{
id __strong strongReference;
id __weak weakReference;
id __unsafe_unretained unsafeReference;
}

- (IBAction)testAlloc:(id)sender;
- (IBAction)testFree:(id)sender;
- (IBAction)print:(id)sender;

@end

@implementation WindowController
...

- (IBAction)testAlloc:(id)sender
{
strongReference = [[NSObject alloc] init];
weakReference = strongReference;
unsafeReference = strongReference;
}

- (IBAction)testFree:(id)sender
{
strongReference = nil;
}

- (IBAction)print:(id)sender
{
NSLog(@"strong: %@", strongReference);
NSLog(@"weak: %@", weakReference);
NSLog(@"unsafe: %@", unsafeReference);
}
@end

ZeroMQ PUB/SUB memo

def sub_handler(sock, events):
    msg = sock.recv()
    print msg

def sub():
    print "*** sub"
    loop = ioloop.IOLoop.instance()
    ctx = zmq.Context()
    sock = ctx.socket(zmq.SUB)
    sock.connect('tcp://127.0.0.1:5555')
    sock.setsockopt(zmq.SUBSCRIBE, '')
    loop.add_handler(sock, sub_handler, zmq.POLLIN)
    loop.start()

def pub():
    print "*** pub"
    ctx = zmq.Context()
    sock = ctx.socket(zmq.PUB)
    sock.bind('tcp://127.0.0.1:5555')
    for i in range(0,10):
        msg = "[%d] Hello" % i
        print "publishing %s" % msg
        sock.send(msg)
        time.sleep(0.5)

ZeroMQ REQ/REP memo

ZeroMQ request/reply memo.
install:

sudo port install py-zmq

py:

import sys
import zmq
from zmq.eventloop import ioloop

def rep_handler(sock, events):
    msg = sock.recv()
    sock.send(msg)

def rep():
    print "*** rep"
    loop = ioloop.IOLoop.instance()
    ctx = zmq.Context()
    sock = ctx.socket(zmq.REP)
    sock.bind('tcp://127.0.0.1:5555')
    loop.add_handler(sock, rep_handler, zmq.POLLIN)
    loop.start()

def req():
    print "*** req"
    ctx = zmq.Context()
    sock = ctx.socket(zmq.REQ)
    sock.connect('tcp://127.0.0.1:5555')
    sock.send('hello')
    print sock.recv()

def main():
    command = sys.argv[1].lower()
    if command == "req":
        req()
    elif command == "rep":
        rep()

main()

node.js memo

install:

sudo port install nodejs
sudo port install netcat

tcp echo server js:

var net = require("net");
net.createServer(function(sock){
    sock.on("data", function(data){
        sock.write(data);
    });
}).listen(8000);

http echo server js:

var http = require("http");
http.createServer(function(req, res){
    res.writeHead(200, {'Content-type' : 'text/plain'});
    res.write("Hello\n");
    res.end();
}).listen(8000);

test client command:

nc localhost 8000
curl http://localhost:8000
1 6 7 8