Best objective-c questions in June 2012

Simulating low battery for iPhones

18 votes

I am working on a mobile game, which appearantly crashes when the Low Battery alert is displayed. It works fine on low memory, incoming calls and other messages.

Its a pain to test and debug this, since I can find no terminal or iPhone simulator way of simulating this situation, so I have to charge my phone up a little bit, launch the app, wait for it to drain its power, and start all over again.

Does anyone know of a way to produce this error in a realistic way? Hopefully something that isn't too stressful on my iPhone battery.

Unfortunately, there is no good way to simulate a low-battery environment. You actually will most likely need to physically charge your device's battery until it is just above the "low battery" state and then debug your application.

To address what others have said:

  1. There is no way to simulate low battery notifications. The project that @Bo. provided does nothing more than schedule random UILocalNotifications. It isn't all that much different than just showing a UIAlertView in your app.
  2. You could try what @Andrew R. said and use the private methods found in the UIDevice header. But it is doubtful that you will exactly mimic the effects of a real low-battery environment.

Although it is a pain to have to wait for you device to actually hit the low-battery state, you could add some battery-draining code to your app to assist you. For example, using the GPS might drain the battery a bit quicker.

Good luck.

"Testing Class Equality" in Objective-c

11 votes

I am having problem understanding this part of "Testing Class Equality" which is defined in apple guide.

In a dynamically-created subclass, the class method is typically overridden such that the subclass masquerades as the class it replaces. When testing for class equality, you should therefore compare the values returned by the class method rather than those returned by lower-level functions. Put in terms of API, the following inequalities pertain for dynamic subclasses:

[object class] != object_getClass(object) != *((Class*)object)

You should therefore test two classes for equality as follows:

if ([objectA class] == [objectB class]) { //...

There are situations in which people add new classes at runtime. One example is Key Value Observing: when you observe an object the Foundation framework creates a new subclass of the observed object's class. This dynamic class behaves in the same way as its superclass, but adds KVO notifications to all of its mutator methods.

The passage you quoted says that the Objective-C runtime can tell this new class apart from the original class. However, because it's just an implementation detail of the way KVO is built, you shouldn't know or care about it. The developers therefore overrode the -class method of their new class, to pretend that objects were still members of the original class.

If you want to check whether two objects are of the same class, you must therefore compare the results of their -class methods (which take tricks like KVO into account), instead of using runtime functions.

Here's an example:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSObject *observer = [NSObject new];
        NSObject *model = [NSObject new];

        [model addObserver: observer forKeyPath: @"count" options: 0 context: NULL];

        //using -class methods:
        NSLog(@"model is a %@, observer is a %@", [model class], [observer class]);

        //casting to Class:
        NSLog(@"model is a %@, observer is a %@", *(Class*)model, *(Class*)observer);

        //using the runtime:
        NSLog(@"model is a %@, observer is a %@", object_getClass(model), object_getClass(observer));

        [model removeObserver: observer forKeyPath: @"count" context: NULL];
        [model release];
        [observer release];
    }
    return 0;
}

You see that all I'm doing is creating two objects, telling one of them to observe the other, then finding out what their classes are. Here are the results:

2012-06-08 08:37:26.904 Untitled 2[896:707] model is a NSObject, observer is a NSObject

2012-06-08 08:37:26.907 Untitled 2[896:707] model is a NSKVONotifying_NSObject, observer is a NSObject

2012-06-08 08:37:26.907 Untitled 2[896:707] model is a NSKVONotifying_NSObject, observer is a NSObject

So as the documentation suggests, it's only the first case (where we compare -class) that does anything the application code could reasonably expect. The other two ways of finding out the class - asking the runtime, and casting the object pointer to a Class * - both give away implementation details about how KVO has changed the class from underneath us, and mean that the class comparison now won't show that the classes are equal.

Because other answers and comments are referring to -isMemberOfClass: and -isKindOfClass:, I'll cover those points too:

  • -isKindOfClass: is not a test for class equality. [object isKindOfClass: aClass] is true if object is an instance of aClass or any of its subclasses. Because the passage you've quoted is about class equality, -isKindOfClass: is not relevant here. That said, it's most often the test that you want to be doing in application code. It's more common to care about the answer to "can I use this object as a Foo?" than "is this object an instance exactly of Foo?".

  • -isMemberOfClass: is a test for class equality: [object isMemberOfClass: aClass] is only true if object is an instance of aClass. This test is done using the result of the -class method, which means that in this example model will test positive for [model isMemberOfClass: [NSObject class]].

So many ways to define a byte

9 votes

Does it make a difference which one I use in objective-c (particularly on iOS)? I assume it comes from inheriting from C and its types, as well as inheriting the types from Mac OS, which iOS was based on, but I don't know which one I should use:

unsigned char from...well..the compiler?

uint8_t from stdint.h

UInt8 from MacTypes.h

Byte from MacTypes.h

Bytef from zconf.h

I am aware that the various defs are for portability reasons, and using literals like unsigned char is not good future thinking (size might change, and things will end up like the Windows API again). I'd like some advice on how to spot the best ones for my uses. Or a good tongue lashing if I'm just being silly...

EDIT : Just for some more info, if I want something that will always be 1 byte, should I use uint8_t (doesn't seem like it would change with a name like that)? I'd like to think UInt8 wouldn't change either but I see that the definition of UInt32 varies on whether or not the processor is 64-bit.

FURTHER EDIT : When I say byte, I specifically mean that I want 8 bits. I am doing pixel compression operations (32 bits -> 8 bits) for disk storage.

It's totally indifferent. Whichever you use, it will end up being an unsigned char. If you want it to look nice, though, I suggest you use uint8_t from <stdint.h>.

Neither will change with the architecture. char is always 1 byte as per the C standard, and it would be insupportable from a user's point of view if in an implementation, UInt8 suddenly became 16 bits long.

issue in drawing line using core graphics : bubbles are shown

9 votes

Using core graphics , I am trying to draw a line, in that when I try to add shadow is creates lin and bubbles inside the line, see the image, I am not able to solve the issue. please find my code below

-(void)drawRect:(CGRect)rect
{

    [curImage drawAtPoint:CGPointMake(0, 0)];
    CGPoint mid1 = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2 = midPoint(currentPoint, previousPoint1);

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    [self.layer renderInContext:context];

    CGContextMoveToPoint(context, mid1.x, mid1.y);
    CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); 
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, self.lineWidth);
    CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);

    CGContextSetShadow(context, CGSizeMake(-16.00, -5.0f), 5.0f);

    CGContextStrokePath(context);

    [super drawRect:rect];

    [curImage release];

}

Below is the touchesMoved method.

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch  = [touches anyObject];

    previousPoint2  = previousPoint1;
    previousPoint1  = [touch previousLocationInView:self];
    currentPoint    = [touch locationInView:self];

    // calculate mid point
    CGPoint mid1    = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2    = midPoint(currentPoint, previousPoint1);

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
    CGPathAddQuadCurveToPoint(path, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
    CGRect bounds = CGPathGetBoundingBox(path);
    CGPathRelease(path);

    CGRect drawBox = bounds;

    //Pad our values so the bounding box respects our line width
    drawBox.origin.x        -= self.lineWidth * 2;
    drawBox.origin.y        -= self.lineWidth * 2;
    drawBox.size.width      += self.lineWidth * 4;
    drawBox.size.height     += self.lineWidth * 4;

    UIGraphicsBeginImageContext(drawBox.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    curImage = UIGraphicsGetImageFromCurrentImageContext();
    [curImage retain];
    UIGraphicsEndImageContext();
   [self setNeedsDisplayInRect:drawBox];

}

CGPoint midPoint(CGPoint p1, CGPoint p2)
{
    return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
}


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch = [touches anyObject];

    previousPoint1 = [touch previousLocationInView:self];
    previousPoint2 = [touch previousLocationInView:self];
    currentPoint = [touch locationInView:self];

    [self touchesMoved:touches withEvent:event];
}

Here the issue arrives when I try to add the line

CGContextSetShadow(context, CGSizeMake(-16.00, -5.0f), 5.0f); 

Issue image

Please help me out from the issue, thanks in advance. please see editing question with methods .

It would appear you are drawing a series of segments as quad curves. The bubbles would be where the previous segment and the current segment overlap. Since your segment line is a solid red, you don't notice the overlap, but it shows up in the shadows as darker regions.

Try setting your stroke color to have and alpha of 0.5 (or some such translucency). I think (know) you will see the overlapping segments will also show a similar effect as the the shadow.

To solve it, you will want to draw the segment as a continuous path for each line. I'm guessing you are using touchesBegan:withEvent: / touchesMoved:withEvent / touchesEnded:withEvent: to obtain the points of the lines?

In that case, when touchesBegan:withEvent: is called, start your new path. During touchesMoved:withEvent render the new path over the current image. Commit the path to a UIImage in touchesEnded:withEvent:. At this point you may discard the path until touchesBegan:withEvent: is called again with the next stroke.

Update

In your code snippets you end up rendering the whole view three times every run loop. That's a lot of drawing overhead. I quickly put together some code that demonstrates what I am talking about above. It is not tested code, but it should be mostly right:

Update 2

I had a bit of time to write and test some code that will do what you are seeking based on my latest two comments. This code is from the view controller instead of the view itself, but with a little modification, you can move in the view if you like. As such, I added an UIImageView as a subview to the generic UIView to hold and display the image (and maintained a reference to in the view controller), and made the view controller the first responder in order to receive the touch events. Lots of hard coded values that you can clean up when integrating into your own project:

static
UIImage *CreateImage( CGRect rect, NSArray *paths )
{
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 1.0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGFloat colorComponents[4] = {0.0,0.0,0.0,0.0};
    CGContextSetFillColor(context, colorComponents);
    CGContextFillRect(context, rect);

    for ( id obj in paths ) {
        CGPathRef path = (CGPathRef)obj;
        CGContextAddPath(context, path);
    }    
    CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor]);
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, 5.0);
    CGContextSetShadow(context, (CGSize){-8.0,40}, 5.0);
    CGContextBeginTransparencyLayer(context, NULL);

    CGContextDrawPath(context, kCGPathStroke);

    CGContextEndTransparencyLayer(context);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

static
CGPoint MidPoint( CGPoint pt1, CGPoint pt2 )
{
    return (CGPoint){(pt1.x+pt2.x)/2.0,(pt1.y+pt2.y)/2.0};
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    CGPoint location = [[touches anyObject] locationInView:self.view];
    myPath = CGPathCreateMutable();
    CGPathMoveToPoint(myPath, NULL, location.x, location.y);

    [self.paths addObject:(id)myPath];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];
    UITouch *touch = [touches anyObject];
    CGPoint previousLocation = [touch previousLocationInView:self.view];
    CGPoint location = [touch locationInView:self.view];
    CGPoint midPoint = MidPoint(previousLocation, location);
    CGPathAddQuadCurveToPoint(myPath, NULL, midPoint.x, midPoint.y, location.x, location.y);

    self.imageView.image = CreateImage(self.view.bounds, self.paths);
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];
    UITouch *touch = [touches anyObject];
    CGPoint previousLocation = [touch previousLocationInView:self.view];
    CGPoint location = [touch locationInView:self.view];
    CGPoint midPoint = MidPoint(previousLocation, location);
    CGPathAddQuadCurveToPoint(myPath, NULL, midPoint.x, midPoint.y, location.x, location.y);

    self.imageView.image = CreateImage(self.view.bounds, self.paths);

    CGPathRelease(myPath);
    myPath = nil;
}

How to know when an user rates an iOS app/game

9 votes

I am developing a game for iOS. I would like to implement a feature that allow the user rate my app and, if he does it, he will get points for my game. I know how to display an screen, menu, whatever to ask the user rate my app, but I don't know how to know when the user does it, I mean, the user completes all the process and I get my valuation.

Thanks so much

The only thing you can do is to use something like Appirater

You could recommend to your clients to review and rate your app. But I think that you don't be able of know if they finally rate or not.

Removing done button in media picker

8 votes

In my app I am using media picker when I click on a button media picker will appear. After selecting the required song I have to press done button to dismiss that picker view.
Instead of that can I have a any chance to dismiss picker view after selecting song without pressing done button?

Thanks in advance!

enter image description here

Alternative , You can use allowsPickingMultipleItems property. Set it to NO.

Learning C for Objective-C

7 votes

I am relatively proficient in Objective-C but I have been looking around some frameworks and libraries I might use in the future and I am increasingly seeing the use of C. So far the only applications I have written contain only Objective-C. I know Objective-C is a superset of C, but what I mean when I say that I have only written in Objective-C is that I have only used Objective-C methods and the syntax of Objective-C that is distinctly different from C syntax. I've been going through questions related to the relationship between C and Objective-C (see links below) and I want to start learning C, but apparently there are three types of C (K&R, C89, and C99), and I am wondering which type I should learn to help me with Objective-C. I know from learning Objective-C I unknowingly learned C too, but I want to understand the ins and outs of C more and become familiar with its functions, syntax, features, etc.

Thanks.

Moving from C to Objective-C?

Objective-C and its relation to C

Objective-C Programming: Will Learning C and/or Smalltalk Help?

----------EDIT------------

Also, is Objective-C based off of any one of the three types of C?

There are even more types of C. In the meantime C0X and C11 were defined... They all make only small evolutionary steps from their predecessors, so you shouldn't worry much about it. Objective-C is based on C99 (minus floating point pragmas, actually), so for now that would probably be the best fit.

It's not entirely clear from your question, but you do notice that those variations of C are just evolving specifications from different years? K&R from ca. 1978, C89 from 1989, C99 from 1999 etc... Objective-C was designed to be a strict superset of C, so you can probably expect Objective-C to incorporate C11 features some day.

(NB: several edits to include information from the comments)

Design pattern for UI controls' state management in iOS

7 votes

Similar to this question, but I am looking for a generic solution or design pattern or framework.

Q. How to add state management into all UI controls in my iOS app automatically without the need to rewrite the existing controls' class?

Example:

e.g. When I click on a UIButton, it will create a new UIWebView showing Google home page. That is easy, but problem arise when user sometimes.. click the button just too fast, so two webview will be displayed.

To solve this question, I would need to make a singleton class which contain the webview, and have a state variable isOpended and if it is true, reuse the existing webview instead of creating a new one.

But the problem is: If I want this behavior in other controls also, then I would need to create many many singleton classes..I am just thinking if there is better way to handle this without the new to re-invent the wheel.

Thanks.

I think you're solving the wrong problem here. Why don't you disable the button until the UIWebView is done processing. That way the user cannot click it twice.

- (IBAction)showMapHomepage:(UIButton*)sender
{
    sender.enabled = NO;
    [self taskThatTakesALongTimeWithCompletion:^{
        sender.enabled = YES;
        // Finish processing
    }];
}

Adding year component to islamic calendar fails

7 votes

Following code shows the problem: Advancing a full year from the first day of the year 1435 does not result in the first day of 1436.

Any ideas what i'm missing?

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:1];
[components setMonth:1];
[components setYear:1435];


NSCalendar *islamic = [[NSCalendar alloc] initWithCalendarIdentifier:NSIslamicCalendar];
NSDate *date = [islamic dateFromComponents:components];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setCalendar:islamic];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];

NSLog(@"%@", [dateFormatter stringFromDate:date]);  // -> 01.01.1435

NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setYear:1];

NSDate *dateWithOffset = [islamic dateByAddingComponents:offsetComponents toDate:date options:0];

NSLog(@"%@", [dateFormatter stringFromDate:dateWithOffset]); 
// -> 30.12.1435 ... WHY NOT 01.01.1436 ????

My suspicion is because of summertime/wintertime (daylight savings time) difference. Muh. 1, 1435 falls on November 5, 2013, while Muh. 1, 1436 falls on October 25, 2014. The first date is during wintertime, the second during summertime.

The first NSDate you created is exactly November 5, 2013 00:00 (at midnight). "dateByAddingComponents:" works by converting the components to seconds, and adding that to the first date. In this case, the result is October 24, 2014 23:00, because of the summertime.

This would also mean that the results could be different for different people around the world because of daylight saving time differences between timezones.

You can prevent the problem by setting the first date to mid-day, instead of midnight (which is in general a good idea when working with pure dates):

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:1];
[components setMonth:1];
[components setYear:1435];
[components setHour:12];

Now, whether this is correct behaviour of "dateByAddingComponents" is another question.

Fast Enumeration on an NSArray category for NSIntegers

7 votes

Since I use NSInteger arrays frequently, I wrote a category for NSArray (and one for NSMutableArray too) that adds methods such as integerAtIndex:, arrayByAddingInteger:, etc. The methods take care of wrapping/unwrapping the NSInteger in an NSNumber object.

What I'm wondering is whether there is a way I can enhance my category so that I can do fast enumeration on the NSIntegers. I would like to be able to write:

NSArray* arrayOfIntegers;
    .
    .
    .

for(NSInteger nextInteger in arrayOfIntegers)
    {
    }

….so that "nextInteger" is pulled out of the NSNumber object behind the scenes. Can I do this?

I doubt that there is a clean way of doing this with NSFastEnumeration, as it heavily depends on the nextObject method.

But, you could do it in another way, by adding a block method for it:

@interface NSArray (Integers)
-(void)eachInteger:(void(^)(NSInteger))block;
@end

@implementation NSArray (Integers)
-(void)eachInteger:(void(^)(NSInteger))block {
  for (NSNumber *num in self) {
    block(num.integerValue);
  }
}
@end

That way, you could use it in your code in a similar way:

NSArray *arr = [NSArray arrayWithObjects:[NSNumber numberWithInt:23],
                                         [NSNumber numberWithInt:42],
                                         nil];
...
[arr eachInteger:^(NSInteger i) {
  NSLog(@"The int is %i", i);
}];
// =>
//    The int is 23
//    The int is 42

Perhaps you might want to take a look at the NSArray categories on the Lumumba Framework, which happens to be written by me :D

Selectors or Blocks for callbacks in an Objective-C library

7 votes

Question:

We're developing a custom EventEmitter inspired message system in Objective-C. For listeners to provide callbacks, should we require blocks or selectors and why?

Which would you rather use, as a developer consuming a third party library? Which seems most in line with Apple's trajectory, guidelines and practices?

Background:

We're developing a brand new iOS SDK in Objective-C which other third parties will use to embed functionality into their app. A big part of our SDK will require the communication of events to listeners.

There are five patterns I know of for doing callbacks in Objective-C, three of which don't fit:

  • NSNotificationCenter - can't use because it doesn't guarantee the order observers will be notified and because there's no way for observers to prevent other observers from receiving the event (like stopPropagation() would in JavaScript).
  • Key-Value Observing - doesn't seem like a good architectural fit since what we really have is message passing, not always "state" bound.
  • Delegates and Data Sources - in our case, there usually will be many listeners, not a single one which could rightly be called the delegate.

And two of which that are contenders:

  • Selectors - under this model, callers provide a selector and a target which are collectively invoked to handle an event.
  • Blocks - introduced in iOS 4, blocks allow functionality to be passed around without being bound to an object like the observer/selector pattern.

This may seem like an esoteric opinion question, but I feel there is an objective "right" answer that I am simply too inexperienced in Objective-C to determine. If there's a better StackExchange site for this question, please help me by moving it there.

Personally, I hate using delegates. Because of how objective-C is structured, It really clutters code up If I have to create a separate object / add a protocol just to be notified of one of your events, and I have to implement 5/6. For this reason, I prefer blocks.

While they (blocks) do have their disadvantages (e.x. memory management can be tricky). They are easily extendable, simple to implement, and just make sense in most situations.

While apple's design structures may use the sender-delegate method, this is only for backwards compatibility. More recent Apple APIs have been using blocks (e.x. CoreData), because they are the future of objective-c. While they can clutter code when used overboard, it also allows for simpler 'anonymous delegates', which is not possible in objective C.

In the end though, it really boils down to this: Are you willing to abandon some older, more dated platforms in exchange for using blocks vs. a delegate? One major advantage of a delegate is that it is guaranteed to work in any version of the objc-runtime, whereas blocks are a more recent addition to the language.

As far as NSNotificationCenter/KVO is concerned, they are both useful, and have their purposes, but as a delegate, they are not intended to be used. Neither can send a result back to the sender, and for some situations, that is vital (-webView:shouldLoadRequest: for example).

How does the iOS app Display Recorder record the screen without using private API?

7 votes

The iOS app Display Recorder claims to be able to record the screen of an iOS device, even while it is in the background. Given that UIGetScreenImage() is private API and will lead to a rejection on application submission when detected by the static analysis Apple runs, how were they able to do this recording in an approved application?

Additionally, the app causes a red bar to appear at the top of the screen while it records, similar to the native iOS's phone call functionality.

I've been an iOS developer for awhile, and I'm a bit stumped at how this was even done, even down to the detail of putting the red bar at the top when outside of the app. I was under the impression we basically had no control of what's happening when the app runs in the background, short of some key pieces of functionality (like audio playing, etc).

Even if the developer tapped into private API/libraries to accomplish this, how were they able to do this in a way that wasn't detected during review? My apologies if I'm missing something obvious that was introduced with a later version of iOS here.

Looked into it and it doesnt link against IOSurface. I did however find that it uses dlsym, and after some more reverse engineering, I found this:

/System/Library/Frameworks/IOKit.framework/IOKit
IOServiceGetMatchingServices
IOServiceGetMatchingService
IOServiceMatching
IOMasterPort
IOIteratorNext
IORegistryEntryCreateCFProperty
IOObjectRelease
/System/Library/Frameworks/UIKit.framework/UIKit
UIGetScreenImage
/System/Library/PrivateFrameworks/IOMobileFramebuffer.framework/IOMobileFramebuffer
IOMobileFramebufferOpen
IOMobileFramebufferGetLayerDefaultSurface
/System/Library/PrivateFrameworks/IOSurface.framework/IOSurface
IOSurfaceAcceleratorCreate
IOSurfaceAcceleratorTransferSurface
IOSurfaceLock
IOSurfaceUnlock
IOSurfaceGetWidth
IOSurfaceGetHeight
IOSurfaceCreate
IOSurfaceGetBaseAddress

So, as you see here, after each framework path are the strings of the symbols that it loads from each framework, dynamically. This is to avoid getting in trouble for linking against a Private Framework. Since it is loaded in at runtime, a static analyzer cannot tell that this app uses it, thereby escaping detection.

It does look like my initial suspicion was correct; it is using IOSurface to sneak past sandbox restrictions to have raw screen access. It also uses UIGetScreenImage, which I assume is for the second method of generating video. It also uses some IOKit functions and IOMobileFramebuffer functions. It looks like the app is grabbing an IOSurface from the IOMobileFramebufferGetLayerDefaultSurface function. Not quite sure what it uses IOKit for though.

In conclusion, this app uses some sneaky techniques to avoid detection by static analyzers: it doesn't link against the private frameworks but instead grabs the symbols dynamically. It uses a combination of IOSurface and IOMobileFramebuffer to record the video, or UIGetScreenImage for the other mode. It is a tricky app that WILL get pulled from the AppStore, so if you want it, you better get it now.

Automatic Scaling of Multipage TIFF NSImage in a CALayer

7 votes

Problem: I have a multipage TIFF image (generated with tiffutil) that contains the same image at multiple pixel dimension from 256x128 px all the way up to 4096x2048 px. I want to display this image in a CALayer so that the system automatically chooses the best representation of the image depending on the layer's size. At the moment, the layer always uses the 256x128 representation of the image, regardless of its size.

Here's what I do: I load the image with

NSImage *image = [NSImage imageNamed:@"map-multipage.tiff"];

Logging the image object confirms that it contains multiple representations with different pixel sizes, but all representations are the same size in points (256x128). AFAIK this is how Apple recommends multi-resolution images to be constructed.

NSLog(@"%@", image);

<NSImage 0x100623060 Name=map-multipage Size={256, 128} Reps=(
    "NSBitmapImageRep 0x10064d330 Size={256, 128} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=256x128 Alpha=NO Planar=NO Format=(not yet loaded) CurrentBacking=nil (faulting) CGImageSource=0x10014fdb0",
    "NSBitmapImageRep 0x10064e1b0 Size={256, 128} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=512x256 Alpha=NO Planar=NO Format=(not yet loaded) CurrentBacking=nil (faulting) CGImageSource=0x10014fdb0",
    ...
    "NSBitmapImageRep 0x100530bd0 Size={256, 128} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=4096x2048 Alpha=NO Planar=NO Format=(not yet loaded) CurrentBacking=nil (faulting) CGImageSource=0x10014fdb0"
)>

I then assign the NSImage instance directly to the layer's contents property:

self.layerView.layer.contents = image;

As mentioned, the result is that the layer uses the first representation (256x128 px) to display the image, regardless of the layer's size in points or pixels.

When I assign the same image to an NSImageView, it works as expected. The image view transparently selects the best image representation depending on its size. I would expect that CALayer would work the same way but apparently this is not the case. Can anybody confirm that CALayer does not support this automatic selection or am I doing something wrong?

(Note that this question is not directly related to HiDPI/Retina graphics. In fact, if I move the layer to a display in HiDPI mode, it does render a little sharper, indicating that it now uses the second bitmap representation (512x256 px) for rendering. This suggests that the automatism to select a higher resolution on a HiDPI display works while the fundamental selection of the best bitmap representation fails.)

It seems like the AppKit method -[CALayer setContents:] chooses a bitmap representation of size matching -[contents size] if contents object is NSImage. Then the selected bitmap is used as is until -[CALayer setContents:] is called once again.

Can I get the C++ preprocessor to send output during compilation?

6 votes

I have been debugging a particularly insidious bug which I now believe to be caused by unexpected changes which stem from different behavior when different headers are included (or not).

This is not exactly the structure of my code but let's just take a look at this scenario:

#include "Newly_created_header_which_accidentally_undefines_SOME_DEFINE.h"

// ...

#ifdef SOME_DEFINE
    code_which_i_believe_i_am_always_running();
#else 
    code_which_fails_which_i_have_forgotten_about(); // runtime error stack traces back here, but I don't know this... or maybe it's some strange linker error
#endif

I search through my git commits and narrow down the cause of the bug, compiling and running my code countless times, only to find after several hours that the only difference required for causing the bug is the inclusion of what appears to be a completely benign and unrelated header.

Perhaps this is a great argument for why the preprocessor basically just sucks.

But I like it. The preprocessor is cool because it lets us make shortcuts. It's only that some of these shortcuts, when not used carefully, bite us in the butt pretty hard.

So at this juncture it would have helped if I could use a directive like #echo "Running old crashy code" where I'll be able to see this during compilation so I could be tipped off immediately to start investigating why SOME_DEFINE was not defined.

As far as I know the straightforward way of determining if SOME_DEFINE is defined is to do something like

#ifndef SOME_DEFINE
    printf("SOME_DEFINE not defined!!\n");

This will surely get the job done but there is no good reason for this task to be performed at runtime because it is entirely determined at compile-time. This is simply something I'd like to see at compile-time.

That being said, in this situation, using the print (or log or even throwing an exception) may be an acceptable thing to do because I won't really care about slowing down or cluttering up the questionable code. But that doesn't apply if I have for instance two code paths both of which are important, and I just want to know at compile-time which one is being activated. I'd have to worry about running the code that does the preprocessor-conditioned print at the beginning of the program.

This is really just a long-winded way of asking the question, "Can I echo a string to the output during compilation by using a preprocessor directive?"

Answer more in line with what I was looking for is here: http://stackoverflow.com/a/3826876/340947

Sorry @sarnold

How to create a NSAutoreleasePool without Objective-C?

6 votes

I have multiplatform game written in C++. In the mac version, even though I do not have any obj-c code, one of the libraries I use seems to be auto-releasing stuff, and I get memory leaks for that, since I did not create a NSAutoreleasePool.

What I want is to be able to create (and destroy) a NSAutoreleasePool without using obj-c code, so I don't need to create a .m file, and change my build scripts just for that. Is that possible? How can that be done?

OBS: Tagged C and C++, because a solution in any of those languages will do.

You can't avoid instantiating the Objective-C runtime—but apparently you've already got one of those.

If you want to interact with the runtime from C, you can us the Objective-C runtime APIs, as documented in Objective-C Runtime Programming Guide and Objective-C Runtime Reference.

The idea is something like this (untested):

#include <objc/runtime.h>
#include <objc/objc-runtime.h>
id allocAndInitAutoreleasePool() {
  Class NSAutoreleasePoolClass = objc_getClass("NSAutoreleasePool");
  id pool = class_createInstance(NSAutoreleasePoolClass, 0);
  return objc_msgSend(pool, "init");
}
void drainAutoreleasePool(id pool) {
  (void)objc_msgSend(pool, "drain");
}

If you want to call these functions from another file, of course you'll have to include objc/runtime.h there as well. Or, alternatively, you can cast the id to void* in the return from the allocAndInit function, and take a void* and cast back to id in the drain function. (You could also forward-declare struct objc_object and typedef struct objc_object *id, but I believe that's not actually guaranteed to be the right definition.)

You shouldn't have to pass -lobjc in your link command.

Needless to say, it's probably less work to just make your build scripts handle .m files.