Best objective-c questions in September 2011

What source comments does Xcode recognize as tags?

8 votes

This is mostly for curiosity's sake. I've known for awhile that Xcode is capable of recognizing comments in the form of // TODO: Something I don't feel like doing now. Adding that line to the source of a file will cause that TODO comment to show up in Xcode's navigation bar:

enter image description here

I also recently discovered that comments of the form // MARK: Something can achieve the same effect as #pragma marking something. So I can write a comment that looks like:

// MARK: -
// MARK: Future Improvements:
// TODO: Make something better
// TODO: Fix some bug

And Xcode will render it out like this:

enter image description here

Which leads me to wonder: Are there other kinds of comments that Xcode can understand to improve project navigation?

There is also FIXME, !!! and ???, e.g.

// FIXME: this bug needs to be fixed

and

// ???: WTF ???

and

// !!!: WTF !!!

You can see where these are defined in /Developer/Library/PrivateFrameworks/XcodeEdit.framework/Resources/BaseSupport.xclangspec - presumably you could also add your own tags here if you wanted to but I have not actually tried this.

These tags are also supported in the BBEdit text editor and its freeware sibling TextWrangler.

Rotating Three20 TTPhotoViewController inside TabBarController

7 votes

Adding Three20 TTPhotoViewController on an empty UIWindow Rotation were working like a charm.

But when I moved the TTPhotoViewController to be created from UINavigationController inside a UITabBarController it does not rotate at all.

I made sure I return YES for every shouldAutorotateToInterfaceOrientation function.

Does Three20 Photo Gallery work in side UITabBarController with rotation?


How am I doing this?

[[TTURLRequestQueue mainQueue] setMaxContentLength:0];

TTNavigator *navigator = [TTNavigator navigator];
navigator.persistenceMode = TTNavigatorPersistenceModeAll;

navigator.window = [UIApplication sharedApplication].keyWindow;
TTURLMap *map = navigator.URLMap;
[map from:@"tt://appPhotos" toSharedViewController:[PhotoViewController class]];
[navigator openURLAction:[TTURLAction actionWithURLPath:@"tt://appPhotos"]];


Update 1: after reading some posts I can now rotate the images only inside the TTScrollView but the navigation bar is not rotating.

Update 2: I have subclass-ed both UITabBarController and UINavigationController to override shouldAutorotateToInterfaceOrientation, but it did not help.

I have weirdly solved my issue by removing the TabBarController from the Window object and when going back I add the TabBarController to the window again.

3 questions about extern used in a Objective-C project

6 votes

1 when I use the word "extern" before a method or variable declaration, am I making it global and therefore readable/writable/usable over the entire project ?

2 If I use extern before a keyword, is there any chance it is still not accessible by part of my project ? For example, only by subclasses.. such as when I use "protected".

3 extern is C keyword right ? Is there an equivalent in Objective C ? I actually don't understand why they use C keyword in an objectiveC project.

thanks

1) you're specifying its linkage. extern linkage allows you or any client to reference the symbol.

regarding global variables: if the variable is mutable and/or needs proper construction, then you should consider methods or functions for this object. the notable exception to this is NSString constants:

// MONClass.h
extern NSString* const MONClassDidCompleteRenderNotification;
// MONClass.m
NSString* const MONClassDidCompleteRenderNotification = @"MONClassDidCompleteRenderNotification";

2) there is no case where the extern keyword affects visibility (public/protected/private/package). to use the symbol (e.g. the constant or C function), simply include the header it is declared in.

somewhat confusing if you are new to the language: placing extern C declarations (constants, functions) in between @interface ... @end will not alter its scope:

@interface MONClass : NSObject

extern const size_t MaximumThreads;

@end

has the same scope (global) and visibility (public) as:

@interface MONClass : NSObject

@end

extern const size_t MaximumThreads;

so it really makes no sense to place your class related C constants or functions in the @interface...@end and @implementation...@end. i recommend placing these in the same header as the interface, outside @interface/@end and @implementation/@end and prefixing the name with the class it is associated with, like so:

@interface MONClass : NSObject

@end

extern const size_t MONClassMaximumThreads;
// MONClass.m
const size_t MONClassMaximumThreads = 23;

and if you want that constant to be private, just declare and define it like this:

// MONClass.m
static const size_t MONClassMaximumThreads = 23;

@implementation MONClass

@end

unfortunately, there is no equally simple or common way to make this constant protected with objc.

finally, you can also use class methods if the number should vary by class:

@interface MONMammal : NSObject
+ (NSUInteger)numberOfLegs;
@end

@implementation MONDog
+ (NSUInteger)numberOfLegs { return 4; }
@end
@implementation MONHuman
+ (NSUInteger)numberOfLegs { return 2; }
@end

3) yes, among other languages. for example, if you use extern const int Something in a c++ translation, the c++ translation will look for Something declared as an extern C++ symbol. there is no substitution in objc; objc is a superset of C and inherits all of C's functionalities. use of extern is well formed and you can also find it in the frameworks you use (e.g. Foundation). they use it because they need to specify linkage. objc does not offer a substitute, presumably because it did not require a replacement or extension.

to avoid this, simply use a #define like this:

#if !defined(__cplusplus)
#define MONExternC extern
#else
#define MONExternC extern "C"
#endif

MONExternC const size_t MONClassMaximumThreads;

NSString format

6 votes

I have a NSString I am getting from an array. There are multiple string objects in the array. I want to change the format of the string I get from array and display that new formatted string on UILabel. let me give one example :
String in array : 539000
String I want to display : 5.390.00

Now the problem is that the string I get from array may be 539000, 14200 or 9050. So the string I want to get are : 5.390.00, 142.00, 90.50
The correct format is :
Place a . before last two digits, again place a . before 3 digits from first .
I hope I have put my query in best possible way. Please help.

Thanks,
Nitish

USE this it will help

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; 
//[formatter setNumberStyle:NSNumberFormatterNoStyle];
//[formatter setPositiveFormat:@"###-###-####"]; 
[formatter setGroupingSeparator:@"."];
[formatter setGroupingSize:2];
[formatter setUsesGroupingSeparator:YES];
[formatter setSecondaryGroupingSize:3];

//[formatter setLenient:YES];
NSString *num = @"539000";
NSString *str = [formatter stringFromNumber:[NSNumber numberWithDouble:[num doubleValue]]];
[formatter release];
NSLog(@"%@",str);

To -lobjc or not to -lobjc?

6 votes

GCC manual says:

file.m
    Objective-C source code. Note that you must link with thelibobjc
    library yo make an Objective-C program work.

And:

-lobjc
    You need this special case of the-loption in order to link an
    Objective-C or Objective-C++ program.

However, I can succesfully compile a program with simply:

$ cc prg.m -framework Foundation

Is it a linker default, when you include a framework? If so, where is it documented? The program gets linked anyway:

$ otool -L a.out
a.out:
        /System/Library/Frameworks/Foundation.framework/.../Foundation (...)
        /usr/lib/libSystem.B.dylib (...)
    --> /usr/lib/libobjc.A.dylib (...)
        /System/Library/Frameworks/CoreFoundation.f...k/.../CoreFoundation (...)

This is because the Foundation framework is already linked with libobjc.

So on OSX, you'll need -lobj option only if you doesn't link with the Foundation framework (which is very rare).

Detect if time format is in 12hr or 24hr format

6 votes

Is there any way to detect if the current device of the app uses 12h our 24h format, so that I can use one NSDateFormatter for 12h and one for 24h depending on the users language/loaction setting? Just Like the UIDatePicker detects and shows the AM/PM picker if it is 12h format.

I figured it out, its pretty easy. I just added this code to viewDidLoad :

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setLocale:[NSLocale currentLocale]];
[formatter setDateStyle:NSDateFormatterNoStyle];
[formatter setTimeStyle:NSDateFormatterShortStyle];
NSString *dateString = [formatter stringFromDate:[NSDate date]];
NSRange amRange = [dateString rangeOfString:[formatter AMSymbol]];
NSRange pmRange = [dateString rangeOfString:[formatter PMSymbol]];
BOOL is24h = (amRange.location == NSNotFound && pmRange.location == NSNotFound);
[formatter release];
NSLog(@"%@\n",(is24h ? @"YES" : @"NO"));

And it perfectly returns YES or NO depending on the locale.

How to tell if object is in an NSAutoreleasePool

6 votes

I would like to know how many times an object has been autoreleased. I've used objective c long enough that it's generally straight forward to know whether an object has been autoreleased or not, however I constantly see questions dealing with memory and retain counts. At some point an answer always ends, "You can't trust the retainCount of an object" - which I agree with, BUT if you could determine how many times an object has been autoreleased, then you actually could trust the retainCount if you added a category like:

@interface NSObject (NSObject_MemoryDebugging)
- (NSUInteger) autoReleaseCount;
- (NSUInteger) retainCountWithAutoRelease;
@end

@implementation]
/** Determine how many times this object has been marked for autorelease **/
- (NSUInteger) autoReleaseCount;
{
   // ??? not sure how to figure this out.
   return 0;
}

 - (NSUInteger) retainCountWithAutoRelease
{
   NSUInteger retainCount = [self retainCount];
   NSUInteger autoReleaseCount = [self getAutoReleaseCount];  // ???
   return retainCount - autoReleaseCount;
}
@end

There would still be an exception for immutable types as those typically increase the retain count during a copy, so you still can't trust retainCount on those.

What I am NOT proposing

I am not seeking this answer to use retainCount in production code. However, I can see this as being valuable for someone debugging memory issues.

I imagine some people will HATE this question since programmers should not care about how many times an object has been autoreleased. Coding should be all about balancing allocs, retain, copy, new with release, end of story. However, the point of this is to help out people banging their heads. [NSObject retainCount] burns a lot of people, and an answer to this question would be pretty cool.

I'm certain there's a way to determine how many times an object has been autoreleased. I just don't know what it is, hence the question.

See similar question: Objects inside NSAutoreleasePool in objective-c.

Edit


Thank you everyone for your answers. You may find this interesting => Ariel pointed out that GNUStep's implementation of Cocoa and specifically it's NSAutoReleasePool has this method: +(NSUInteger)autoreleaseCountForObject:(id)anObject. This method is slow, and only returns the autorelease count from NSAutoReleasePools on the callers thread. Still... It's interesting that its there. The docs cite that it is really only useful for debugging. This is really what I was hoping to find (or find possible) in the Cocoa framework somehow.

I agree with the answers given that even if it were possible to get the autorelease count that better tools exist (Zombies, Leaks, static analyzer).

First, you'd have to deal with multiple autorelease pools and an object being autoreleased more than once, possibly in multiple pools.

Second, it's not (just) NSAutoreleasePool that's making -retainCount untrustworthy. The problem is that all sorts of objects, both yours and Apple's, retain things for all sorts of reasons, most unbeknownst to you. Even accounting for autorelease, your objects will often not have the retain count you expect, because behind the scenes, something's observing it or placing it in a dictionary temporarily, etc.

The best ways to debug memory issues are the Leaks instrument, NSZombie, and the static analyzer.

Is there a simple way (in Cocoa/iOS) to queue a method call to run once in the next run loop?

6 votes

UIView has a setNeedsDisplay method that one can call several times within the same event loop, safe in the knowledge that the redrawing work will happen soon, and only the once.

Is there a generic mechanism for this sort of behaviour Cocoa? A way of of saying, "Queue a selector as many times as you like, when it's time, the selector will run once & clear the queue."

I know I could do this with some kind of state tracking in my target, or with an NSOperationQueue. I'm just wondering if there's a lightweight approach I've missed.

(Of course, the answer may be, "No".)

setNeedsDisplay is not a good example of what you're describing, since it actually does run every time you call it. It just sets a flag. But the question is good.

One solution is to use NSNotificationQueue with NSNotificationCoalescingOnName.

Another solution is to build a trampoline to do the coalescing yourself. I don't have a really good blog reference for trampolines, but here's an example of one (LSTrampoline). It's not that hard to build this if you want to coalesce the messages over a period of time. I once built a trampoline with a forwardInvocation: similar to this:

- (void)forwardInvocation:(NSInvocation *)invocation {
  [invocation setTarget:self.target];
  [invocation retainArguments];
  [self.timer invalidate];
  self.timer = [NSTimer scheduledTimerWithTimeInterval:self.timeout invocation:invocation repeats:NO];
}

This actually coalesces all messages to the object over the time period (not just matching messages). That's all I needed for the particular problem. But you could expand on this to keep track of which selectors are being coalesced, and check your invocations to see if they match "sufficiently."

To get this to run on the next event loop, just set timeout to 0.

I keep meaning to blog about trampolines. Required shilling: My upcoming book covers trampolines in Chapter 4 and Chapter 20.

Is divide slower than Multiply?

5 votes

Ok, this might sound like a strange question but it is an interesting one. I am coding for iOS and have been told that it is always best to multiply rather than divide values as it is faster.

I know that processors these days probably make this a non issue but my curiosity has gotten the better of me and I am wondering if anyone might be able to shed some light on this for me.

SO..... My question is this -
is:

player.position = ccp(player.contentSize.width / 2, winSize.height / 2);

slower than:

player.position = ccp(player.contentSize.width * 0.5, winSize.height * 0.5);

On most processors division is slower than multiplication for the same data types. In your example your multiplication is a floating point operation, if width and height are integer types, the result may be very different and may depend on both your processor and your compiler.

However most compilers (certainly GCC) will translate a division by a constant power-of-two as in your example, to a right-shift where that would be more efficient. That would generally be faster than either a multiply or divide.

Why do Objective-c protocols adopt other protocols?

5 votes

I've seen Objective-c protocols defined in the following way:

@protocol MyProtocol <SomeOtherProtocol>
// ...
@end

Why do protocols adopt other protocols? I'm especially curious why a protocol would adopt the NSObject protocol.

It is simply the same concept as inheritance for classes. If a protocol adopt another protocol, it "inherits" the declared methods of this adopted protocol.

The NSObject protocol especially declares methods such as respondsToSelector:. So this is especially useful if you declare a @protocol that have @optional methods, because when you will then call methods on objects conforming this protocol, you will need to check if the object responds to the method before calling it if this method is optional.


@protocol SomeProtocol <NSObject>
-(void)requiredMethod;
@optional
-(void)optionalMethod;
@end

@interface SomeObject : NSObject
-(void)testMyDelegate;
@property(nonatomic, assign) id<SomeProtocol> myDelegate;
@end

@implementation SomeObject
@synthesize myDelegate

-(void)testMyDelegate {
    // Here you can call requiredMethod without any checking because it is a required (non-optional) method
    [self.myDelegate requiredMethod];

    // But as "optionalMethod" is @optional, you have to check if myDelegate implements this method before calling it!
    if ([myDelegate respondsToSelector:@selector(optionalMethod)]) {
        // And only call it if it is implemented by the receiver
        [myDelegate optionalMethod];
    }
}
@end

You will only be able to call respondsToSelector on myDelegate if myDelegate is declared as a type that implements respondsToSelector (otherwise you will have some warnings). That's why the <SomeProtocol> protocol needs to adopt itself the <NSObject> protocol, which itself declares this method.

You may think of id<SomeProtocol> as "any object, whatever its type (id), it just has to implement the methods declared in SomeProtocol, including the methods declared in the parent protocol NSObject. So it can be an object of any type but because SomeProtocol adopts the NSObject protocol itself, it is guaranteed that you are allowed to call respondsToSelector on this object, allowing you to check if the object implements a given method before calling it if it is optional.


Note that you may also not make SomeProtocol adopt the NSObject protocol and instead declare your variable as id<SomeProtocol,NSObject> myDelegate so that you can still call respondsToSelector:. But if you do that you will need to declare all your variables this way everywhere you use this protocol... So this is much more logical to make SomeProtocol directly adopt the NSObject protocol ;)

annotation on current location

5 votes

I'm working on the project in which i added a button on pressing it should take me to my current location on map and should show the blue indicator to indicate the location,here is the code:

-(IBAction)gotoLocation
{
if(curntloc)
 {
    MKCoordinateRegion mapRegion;   
    mapRegion.center = mapView.userLocation.coordinate;
    mapRegion.span.latitudeDelta = 0.0112872;
    mapRegion.span.longitudeDelta = 0.0112872;
    [self.mapView setRegion:mapRegion animated: YES];
 }
else
  { 
    curntloc = [[CLLocation alloc] initWithLatitude:21.192415 longitude:72.821159];
    MKCoordinateRegion mapRegion;
    mapRegion.center = mapView.userLocation.coordinate;
    mapRegion.span.latitudeDelta = 0.0112872;
    mapRegion.span.longitudeDelta = 0.0112872;
    [self.mapView setRegion:mapRegion animated: YES];
  }
}

This works fine on simulator you can see it in image,

on top is the button on pressing which i get the location statically passed on second loop but on iPhone it won't works

but when i try to test it on iPhone it's getting crashed.what may be the possible reasons can any one point out? thanks

First of all i want to tell you that from simulator you can't get current location. in your code you just used a static lat. long. and for the device i share a link just check.

http://pastebin.com/Vv1wvyBh

which may be helpful to you :)

Thanks.

Calculate APR (annual percentage rate) Programatically

5 votes

I am trying to find a way to programatically calculate APR based on

  • Total Loan Amount
  • Payment Amount
  • Number of payments
  • Repayment frequency

There is no need to take any fees into account.

It's ok to assume a fixed interest rate, and any remaining amounts can be rolled into the last payment.

The formula below is based on a credit agreement for a total amount of credit of €6000 repayable in 24 equal monthly instalments of €274.11.

enter image description here

(The APR for the above example is 9.4%)

I am looking for an algorithm in any programming language that I can adapt to C.

Any help would be much appreciated.

I suppose you want to compute X from your equation. This equation can be written as

f(y) = y + y**2 + y**3 + ... + y**N - L/P = 0

where

X = APR
L = Loan (6000)
P = Individual Payment (274.11)
N = Number of payments (24)
F = Frequency (12 per year)
y = 1 / ((1 + X)**(1/F))   (substitution to simplify the equation)

Now, you need to solve the equation f(y) = 0 to get y. This can be done e.g. using the Newton's iteration (pseudo-code):

y = 1  (some plausible initial value)
repeat 
    dy = - f(y) / f'(y)
    y += dy
until abs(dy) < eps 

The derivative is:

f'(y) = 1 + 2*y + 3*y**2 + ... + N*y**(N-1)

You would compute f(y) and f'(y) using the Horner rule for polynomials to avoid the exponentiation. The derivative can be likely approximated by some few first terms. After you find y, you get x:

x = y**(-F) - 1