Archive for the ‘iPhone’ Category.

[super dealloc];

Sorry about the delay between posts, readers. I have been fighting with getting as much coded as possible with our newest iPhone application, along with fighting with bugs and crashes in our existing iPhone applications. The App Store approval process continues to baffle me to no end.

From a development perspective, one thing I learned the hard way was to make sure that the dealloc methods in the classes that you roll in Objective C need to have the [super dealloc]; come last. If it does not come last, your code may or may not have memory problems and crashes.  If you are not sure if you are always doing this last, check your classes now.

Go ahead and check, I’ll be here when you get back.

“self” is a four letter word

I don’t like to get strange memory crashes in my applications. So imagine my surprise today when I changed over some CFUUIDRef ivars to NSString, and as a result, I started getting some weird EXC_BAD_ACCESS messages.

For your perusal, consider listing A, where my class is being initialized with a nonatomic and retained property:

@synthesize nameString;
 
- (id)initWithData:(NSString *)inNameString
{
    self = [super init];
 
    if (self)
    {
        nameString = inNameString;
    }
 
    return self;
}

After awhile of beating my head against the wall, I changed it to look more like listing B:

@synthesize nameString;
 
- (id)initWithData:(NSString *)inNameString
{
    self = [super init];
 
    if (self)
    {
        self.nameString = inNameString;
    }
 
    return self;
}

I leave it to the reader to investigate this phenomenon. It is not too complicated, but if the subtlety is lost on you, there is always a memory based crash lurking around the corner.

Needless to say, if you are having strange memory crashes in your application, and your class looks like listing A, change it to look more like listing B. And if your app looks like listing B, it is working fine and you want to see how bad bad can really get, change it to look more like listing A.

EXC_BAD_ACCESS in a UIScrollView

After using my latest iPhone application on a device for a while, I was getting the following crash:

Program received signal:  “EXC_BAD_ACCESS”.
(gdb) backtrace
#0  0x33369ebc in objc_msgSend ()
#1  0x320e5248 in -[UIScrollView(UIScrollViewInternal) _scrollViewAnimationEnded] ()
#2  0x338b4a14 in -[NSObject performSelector:withObject:] ()
#3  0x320e5098 in -[UIAnimator stopAnimation:] ()
#4  0x320e4b7c in -[UIAnimator(Static) _advance:] ()
#5  0x320e4a34 in LCDHeartbeatCallback ()
#6  0x34350e60 in HeartbeatVBLCallback ()
#7  0x332e91c0 in IOMobileFramebufferNotifyFunc ()
#8  0x316532f8 in ?? ()
#9  0x33866b50 in __CFMachPortPerform ()
#10 0x338ae52a in CFRunLoopRunSpecific ()
#11 0x338adc1e in CFRunLoopRunInMode ()
#12 0x3434e1c8 in GSEventRunModal ()
#13 0x32002c30 in -[UIApplication _run] ()
#14 0x32001230 in UIApplicationMain ()
#15 0x00002ff8 in main (argc=1, argv=0x2ffff550) at /Developer/svn/MyCompany/iPhone/MyApplication/Other Sources/main.m:14

As you can see from the trace, the only mention of my code in there is the call to main.

I ran Build and Analyze from Xcode, and also set it up to run the clang analyzer on my project from the Terminal, and both of these did not find any problems in the code.

After using the NSZombieEnabled flag in the application, it came up with this message in the console:

2010-09-11 17:10:33.970 MyApplication[9321:207] ***
-[MyViewController respondsToSelector:]: message sent to deallocated instance 0x7489480

I think we finally tracked down a way to keep the error from occurring. I am guessing that the view was being deallocated and released while it was still undergoing a scroll animation. I changed my code to be like this:

[myTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:idx inSection:mainSection]
        animated:NO scrollPosition:UITableViewScrollPositionMiddle];

The application has not crashed with the same error since I changed all of these selectRowAtIndexPath calls to use the NO flag for the animated property. True, this does not fix the problem, but at this point, hiding it was good enough for me and our complaining customers.

Second iPhone app approved

After 9 days, my company’s second iPhone app, Football Statware, was approved on Sunday, August 22, 2010, and is available for download from the App Store.

I have already pushed an update to the application with a few minor fixes, we will see how long this update takes.

Second iPhone app submitted

This past Friday, I submitted my company’s second iPhone application to the App Store for approval. We did not do any profiling on this application for performance or memory leaks, but hopefully it will go through without incident. Stay tuned.

Highly useful Objective-C code

I just got the inspiration to add the following line of code to the app delegate header of my latest iPhone application:

#define  VERY_YES  YES

If you are wondering about the etymology of this, please check out the following informational message:

Where does the term “very yes” originate from?

I leave it to the imagination and creativity of my fellow developers to adapt this code to run in other flavors of C.  Please make sure to credit me if you decide to use it.

The O in iOS is for Orchestra (CIDUG meeting, July 27, 2010)

Geoffrey Goetz gave a presentation on iPhone application development at the Columbus iPhone Developer User Group on July 27, 2010. His topic was mainly a recap of some of the application approval and performance issues that were covered at the 2010 WWDC.

The most interesting part of his presentation for me was his presentation on using the Zombies feature of Instruments. We had some random crashes going on in our Basketball Statware application, and this might have helped to chase down the problem. As it was, I believe we fixed the problem by moving like named variables just sitting by themselves in the implementation files inside the class as class variables.

NSLogTable improvements

Are you tired of seeing the date, time (with seconds and even milliseconds), application name and other stuffs appearing at the beginning of each and every line of the debugging console? You know, the NSLog lines that you use for debugging purposes that look like this:

2010-07-22 20:42:46.998 MyApplicationName[246:207] Setting up reachability notifier
2010-07-22 20:42:47.006 MyApplicationName[246:207] Version: 0.6
2010-07-22 20:42:47.007 MyApplicationName[246:207] Checking for database
2010-07-22 20:42:47.007 MyApplicationName[246:207] Database exists

This information can be helpful, but for the purposes of my utility class that outputs the contents of a SQLite3 database table (see my blog post entitled Nicely formatted data to debugger console for iPhone SDK), this is very annoying as it takes up a lot of the debugging console window.

Well, I decided to look to see if I could output to the debugging and remove the date, time, and application name from the beginning of each line. As it turns out, I found that you cannot do this with NSLog, but luckily I found the following web page that contained the answer:

A Different NSLog()

Even though the web page is for Cocoa development, there is nothing Mac OS X specific looking in there, so I copied the QuietLog function and pasted it into my NSLogTable implementation file, and now I can see much more of my nicely formatted tables since the left 33% of my screen is not filled up with useless dates, times, application names, and thread identifiers.

Here is now what my NSLogTable.m file looks like. (The NSLogTable.h file is unchanged.)

//
//  NSLogTable.m
//
 
#import "NSLogTable.h"
 
@implementation NSLogTable
 
void QuietLog (NSString *format, ...) 
{
    if (format == nil) {
        printf("nil\n");
        return;
    }
 
    // Get a reference to the arguments that follow the format parameter
    va_list argList;
    va_start(argList, format);
 
    // Perform format string argument substitution, reinstate %% escapes, then print
    NSString *s = [[NSString alloc] initWithFormat:format arguments:argList];
    printf("%s\n", [[s stringByReplacingOccurrencesOfString:@"%%" withString:@"%%%%"] UTF8String]);
 
    [s release];
    va_end(argList);
}
 
+ (void)dumpTable:(NSMutableArray *)rows
{
	int idx = 0;
	NSMutableArray *rowData;
	int colWidths[100];
	NSString *s;
	NSMutableString *ms = [[NSMutableString alloc] init];
	BOOL firstRow = YES;
 
	for (int i = 0; i < 100; i++) colWidths[i] = 0;
 
	// get the maximum column widths
	for (id row in rows)
	{
		rowData = (NSMutableArray *)row;
		for (int i = 0; i < [rowData count]; i++)
		{
			s = [rowData objectAtIndex:i];
			if ([s length] > colWidths[i])
			{
				colWidths[i] = [s length];
			}
		}
	}
 
	for (id row in rows)
	{
		[ms setString:@""];
		if (firstRow)
		{
			[ms appendString:@"     "];
			firstRow = NO;
		} else {
			[ms appendFormat:@"%4d ", idx];
		}		
 
		rowData = (NSMutableArray *)row;
		for (int i = 0; i < [rowData count]; i++)
		{
			s = [rowData objectAtIndex:i];
			[ms appendString:[s stringByPaddingToLength:colWidths[i] withString:@" " startingAtIndex:0]];
			[ms appendString:@" "];
		}
 
		QuietLog(@"%@", ms);
		idx++;
	}
 
	[ms release];
	QuietLog(@"");
}
 
@end

Two more iPhone SDK facts you may not know

Here are two other fun facts I discovered about the iPhone SDK:

1. You can present a modal view controller on top of another modal view controller

This would appear to contradict fact #2 from my posting of July 13th, but I have learned some new information. In my previous attempts to stack up modal view controllers, I was sending the presentModalViewController method call to the navigation controller defined in my app delegate. For the second modal view controller, if I just send the presentModalViewController method call in the first view controller to self, all works as it should.

2. Watch your colons on delegate selectors

I was trying to wire up a cancel delegate call that passed no parameters back to the caller, since none are necessary. However, the cancel delegate that I copied and changed from the working accept delegate was never firing in the following code:

if (delegate && [delegate respondsToSelector:@selector(myDelegateCancelPressed:)]) {
    [delegate myDelegateCancelPressed];
}

After I removed the colon from inside the @selector, it worked right as rain.

Two iPhone SDK facts you may not know

I discovered (quite by accident) two things today about iPhone software development. These are things that are probably documented and discussed elsewhere, so here is yet another documenting/mentioning of them.

1. The order of stuff in Interface Builder is actually pretty important

So I am in Interface Builder, copying and pasting some repetitive stuff. I usually like to have the document window open on the left of the screen, the view open middle left, the inspector middle right, and the library on the right. And every once in a while, the stuff I pasted that showed up at the bottom of the list of controls in my view disappeared.

As it turns out, this was happening when I was subconsciously sending the newly pasted controls to the back, and as you may not know, the order of the controls as shown in a view pertains exactly to the z-order of the controls. The control that I was sending to the back going to the top of the list of controls under the view in the document window.

2. Don’t try to present a modal view controller on top of another modal view controller

The subject above says it all. If you create a view controller and use the presentModalViewController method, nothing really happens. The new view is created, but just sort of fizzles out before reaching the screen. (Or in other words, the init is called, but viewDidLoad is never reached.)

This will present a bit of a challenge, as just about every other environment I have worked in allows you to lay modals on top of other modals.