Deprecated: Function split() is deprecated in /mnt/home/cn/cn-web/songshu/lib/pages/DisplayBlogArticleList.php on line 36
Articles matching: objective-c
Ninjas are deadly. Chipmunk Ninjas are just weird.
About this blog
Marc Travels
Marc on Twitter
JustLooking on Twitter

Marc Wandschneider is a professional software developer with well over fifteen years of industry experience (yes, he really is that old). He travels the globe working on interesting projects and gives talks at conferences and trade shows whenever possible.

My Publications:

My book, "Core Web Application Programming with PHP and MySQL" is now available everywhere, including

My "PHP and MySQL LiveLessons" DVD Series has just been published by Prentice-Hall, and can be purchased on Amazon, through Informit, or Safari


Popular Articles:

Top Tags:

Recent Comments:

cncool wrote:

GLint zeroOpacity = 0;
[[self openGLContext] setValues:&zeroOpacity forParameter:NSOpenGLCPS...
Posted to: Things I've learned about CoreImage (and Quartz, and OpenGL) in two weeks
Feb 21, 2009 | 01:27:14
Economic Slowdown in China?
By marcwan

When visiting the USA last summer for some business, the Beijing Summer Olympics were but 3 weeks away, and the hysteria in the West was at a frenzy: The Chinese are going to take over the world proclaimed seemingly every other news source. Radio shows were filled with people talking about the coming Chinese threat, and how the American way of life was at threat due to the waking dragon 4000 miles to the west. Even in Canada, during my visit there, there was a hefty amount of anxiety about the new world order and how things would never be the same.

One of the nice thing about events such as the Olympics, however, is that they focus the attention for only a short period of time, and talk of China in the West seems to have receded to more normal levels, especially as navel-gazing increases while governments try to solve the messes in their own backyards.

The question I am most frequently asked now is: How is the economic crisis affecting China? Is there evidence of a huge slowdown there? Like most things in China, it’s hard to say: there are few statistics offered by anybody, and those that are offered tend to be heavily manipulated and untrustworthy.

So, without any official data, lets look at the available anecdotal evidence:

  • Newspapers are full of stories of factories closing left and right, especially in the industrial heartland of the Pearl river Delta in Guangdong Province. People are going home en masse to the provinces, and not planning on going back.
  • Politicians are suddenly going out of their way to be seen as friendly to farmers. With so many farmers newly returned to the countryside and not as willing to tolerate a lousy feudal existence, the recent drought plaguing the entire northeast of the country is getting serious attention from all levels of government. Most of the unrest and protests in the country occur in smaller towns and villages, and keeping those people happy will be a priority for the Party.
  • In the big cities, real estate prices are markedly down. In Shenzhen, Nanjing, Hangzhou, and other major cities countrywide, real estate has fallen from 2500$ – 3500$ USD per square metre (purchase price) to well below 2000$ USD/m2. Worse, people who have placed deposits on apartments at the higher prices are demanding money back from developers who, desperate to fill the their units, are selling the remaining ones at hefty discounts.
  • Rents in Beijing are down at least 15%, if not more. At the high end, in apartments that cater to foreigners, rents have sometimes even dropped dramatically. I saw one new building here in the east 2nd ring road that was advertising 1BR units (about 90m sq, or 1000 sq f) for 1200$ USD not six months ago, and is now as low as 700-750$ USD per month. Even in the cheaper, lower glamour units that cater more to locals, rents that were 4000 RMB (575$ USD) per month are now going for, at most, 3400 RMB (490$ USD).
  • Food and restaurant prices are markedly up over the last two years, much more so than one would easily attribute to normal inflation levels.
  • The Chinese stock markets are down – way down – from late 2007 levels, often by over 70%. Locals who used to spend money completely recklessly because the stock markets would make it all back are much more cautious now. A recent 30% surge in the market already seems to be fading.
  • For an “on the street” measure, Yoga studios are hurting. Memberships, which were selling out at well over 8000 RMB a year (1150$ USD or so) are now heavily discounted into the 5500 RMB (< 800$ USD) range and you don’t see as many students being driven up in their chauffeured black Audis as before.
  • And at an even more “on the street feeling” level, fireworks during this year’s Spring Festival – the Chinese Lunar New Year – were the lowest in the three years I’ve seen them. Whereas, two years ago, the first night of spring festival was an insane war zone from 6pm until 3am, this year, it was mildly exciting from 8pm until 1am, but by 1.30am, most of it had died out and I was able to get a good night’s sleep without much interruption. This is a slightly tongue in cheek measurement, as much of the reduction could be attributed to the novelty of fireworks simply wearing out. 2007 was the first year in over 15 years that the central government allowed fireworks.

Evidence that goes against an economic slowdown exists to some degree too, however, and must be noted:

  • Retail spending appears strong. Statistics all point to it being quite robust, and anecdotal evidence shows many of the local shopping malls and department stores doing booming business many days of the week. Whether people are purchasing as much or just browsing more is hard to tell, and there definitely is a lot more heavy discounting in the retail chain.
  • Car registrations here in the country’s capitol continue to accelerate. In the first 45 days of the year, there were nearly 70.000 cars licensed with the city government, or well over 1500 a day.

Talking to people, more and more conversations do seem to involve the words jīngjìwēijī (经济危机), or economic crisis, and most Chinese people I know remain as frugal as they’ve always been, so it’s quite wise that the central government avoided any tax breaks or cash handouts to the locals, as they would simply save it and inject almost nothing into the economy.

Are things slowing here? Definitely? Is the crisis going to be a major disaster for the country and government in particular? Much harder to tell.

A note on the picture above: one of the questions I ask myself about China is why do they constantly design crappy buildings or (in this case) plazas/squares that don’t handle things like drainage (or wind, cold, rain, etc) properly.

The answer: it’s significantly cheaper to just hire people to squeegee away the water than to pay the extra to money solve these problems at design/construction time. This applies in so many situations.

[Read Rest of Article]
Oct 26, 2006 | 07:15:59
Cocoa Programming: How to fetch Paper Names, Localised Names, and Page Sizes for a Printer
By marcwan

For a recent project written in Cocoa for Mac OS X, I found myself wanting to get the following set of information for a particular printer:

  • A list of all available paper types
  • Printable names for these paper types
  • Page Sizes
  • Imageable Margins for those same pages.

It turns out that there is no way to get this in Cocoa, and actually it’s not all that easy to find this information in Carbon either.

So, after some research and investimigation on the Intarwebs, as well as much combing through the various PM* header files (buried so deep in a directory on my machine that I had to save the directory name somewhere so I’d be able to find them again!), I’ve come up with the following method to do all the above.

It returns an NSArray. Each paper type supported by the printer gets one item in the array, which is an NSDictionary set-up to use key/value pairs. There are the following pairs:

  • PAPER_NAME (NSString): The system name for the paper.
  • LOCALISED_PAPER_NAME (NSString): The display name for the paper.
  • PAPER_SIZE (NSValue): The size of the paper in 72dpi User Space Units. Use [NSValue -sizeValue] to get the actual value.
  • PAPER_IMAGEABLE_MARGINS (NSValue): The imageable bounds of the paper in 72dpi User Space Units. Use [NSValue -rectValue] to get the actual value.

I’ve noticed that there are some issues with memory allocation in the following code: If I run it a few hundred thousand times, I start to see some memory leaks, which is most upsetting. Given that I can’t free anything else in this code without crashing it, I worry that it might be a system leak. However, given how rarely this code is ever executed (maaaaayyybe 5-10x per process lifetime in an extremely print happy case), It’s something that can be investigated later.

Here be the code, laddies:

+ (NSArray *)paperSizesAndNamesForPrinter: (NSString *)printerName
    PMPrintSession printSession = NULL;
    CFArrayRef printerList = NULL;
    PMPrinter thisPrinter = NULL;
    int numPrinters;
    OSStatus err;
    int i;

    err = PMCreateSession(&printSession);
    if (err != noErr)
        [JLUnknownPrinterErrorException generate];

         * Get a list of all printers.
        err = PMServerCreatePrinterList(kPMServerLocal, &printerList);
        if (err != noErr)
            [JLUnknownPrinterErrorException generate];

         * Now, loop through them until we find the printer we're looking
         * for.  Then we can get the properties.  We throw if the printer
         * isn't found.
        numPrinters = CFArrayGetCount(printerList);
        for (i = 0; i < numPrinters; i++)
            CFStringRef thisPrinterName;
            thisPrinter = (PMPrinter)CFArrayGetValueAtIndex(printerList, i);

            thisPrinterName = PMPrinterGetName(thisPrinter);
            if ([(NSString *)thisPrinterName caseInsensitiveCompare: printerName] == NSOrderedSame)
                return [NSPrinter extractInfoFromPrinter: thisPrinter];

            thisPrinter = NULL;
         * Clean up.  Exceptions will still throw back up the stack.
        if (printerList != NULL) CFRelease(printerList);

    return nil;

+ (NSArray *)extractInfoFromPrinter: (PMPrinter)printerInfo
    NSMutableArray *outputArray = [NSMutableArray arrayWithCapacity: 10];
    CFStringRef paperName = NULL, localised = NULL;
    NSMutableDictionary *paperProps;
    CFArrayRef paperList;
    PMPaper thisPaper;
    int j, numPapers;
    OSStatus err;

     * First, get a list of the paper sizes and create an NSArray 
     * for them all.
    err = PMPrinterGetPaperList(printerInfo, &paperList);
    if (err != noErr)
        [JLUnknownPrinterErrorException generate];

        numPapers = CFArrayGetCount(paperList);
        for (j = 0; j < numPapers; j++)
            NSValue *imageableMargins, *paperSize;
            double paperHeight, paperWidth;
            NSRect adjustedMargins;
            PMPaperMargins margie;

            thisPaper =  (PMPaper)CFArrayGetValueAtIndex(paperList, j);

             * Get the system non-localised paper name.
            PMPaperGetID(thisPaper, &paperName);

             * Get the localised paper name.
            err = PMPaperGetName(thisPaper, &localised);
            if (err != noErr)
                [JLUnknownPrinterErrorException generate];

             * Finally, build up the size.
            err = PMPaperGetHeight(thisPaper, &paperHeight);
            if (err != noErr)
                [JLUnknownPrinterErrorException generate];
            err = PMPaperGetWidth(thisPaper, &paperWidth);
            if (err != noErr)
                [JLUnknownPrinterErrorException generate];

            paperSize = [NSValue valueWithSize: NSMakeSize(paperWidth, paperHeight)];

             * This gets the imageable margins for the page type, which
             * is very useful.
            PMPaperGetMargins(thisPaper, &margie);
            adjustedMargins = NSMakeRect(margie.left,,
                                         (paperWidth - margie.left - margie.right),
                                         (paperHeight - - margie.bottom));
            imageableMargins = [NSValue valueWithRect: adjustedMargins];

             * Finally, create a dictionary with these values and then add
             * them to da array.
            paperProps = [NSMutableDictionary dictionaryWithCapacity: 3];
            [paperProps setValue: [NSString stringWithString: (NSString *)paperName]
                        forKey: PAPER_NAME];
            [paperProps setValue: [NSString stringWithString: (NSString *)localised]
                        forKey: LOCALISED_PAPER_NAME];
            [paperProps setValue: paperSize forKey: PAPER_SIZE];
            [paperProps setValue: imageableMargins forKey: PAPER_IMAGEABLE_MARGINS];

            [outputArray addObject: paperProps];

            paperName = NULL;
            localised = NULL;
        if (paperName) CFRelease(paperName);
        if (localised) CFRelease(localised);

    return outputArray;

I actually implemented this as a category on NSPrinter. You can do this too by simply creating the following header:

#import <Cocoa/Cocoa.h>

#define PAPER_NAME               @"paper_name"
#define LOCALISED_PAPER_NAME     @"localised_paper_name"
#define LOCALIZED_PAPER_NAME     @"localised_paper_name"
#define PAPER_SIZE               @"paper_size"
#define PAPER_IMAGEABLE_MARGINS  @"printable_margins"

@interface NSPrinter (MyNSPrinterExtensions)

// returns an NSArray of NSDictionaries: see constants above.
+ (NSArray *)paperSizesAndNamesForPrinter: (NSString *)printerName;
+ (NSArray *)extractInfoFromPrinter: (PMPrinter)printerInfo;


Finally, you’d then wrap the above two functions in

@implementation NSPrinter (MyNSPrinterExtensions)



Sorry if you’ve got a small screen and this article scrolls horizontally. I’ve decided that, unlike other languages that I can easily keep to 80 columns (or even 65 for writing articles), Objective-C simply requires huge amounts of horizontal real estate.

Also, like most of my code, this uses the new Objective-C structured exception handling, which requires Mac OS X 10.3.9 or greater. If you’re not using it, you should be. I was slow to get into SEH when I first saw them many years back, but now I feel any language is incomplete without them.

[Read Rest of Article]
Copyright © 2005-2008 Marc Wandschneider All Rights Reserved.