Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode - EXEC_BAD_ACCESS when concatenting a large string

I'm getting a EXEC_BAD_ACCESS when concatenting a large string.

I've read from a feed and to create my webview I build up my string like:

NSString *pageData = @"<h1>header</h1>";

pageData = [pageData stringByAppendingFormat@"<p>"];
pageData = [pageData stringByAppendingFormat@"self.bodyText"];
pageData = [pageData stringByAppendingFormat@"</p>"];
etc

The problem I've got is self.bodytext is 21,089 characters with spaces when I do a count on word. Is there a better method for doing this?

Thanks

like image 383
Frames1984 Avatar asked Jan 19 '26 00:01

Frames1984


2 Answers

You would definitely want to use NSMutableString for something like this:

NSMutableString * pageData = [NSMutableString stringWithCapacity:0];

[pageData appendFormat:@"<h1>header</h1>"];
[pageData appendFormat:@"<p>"];
...

NSMutableString is designed for this kind of sequential concatenation, where the basic NSString class is really not meant to be used in this manner. Your original code would actually allocate a new NSString every time you called stringByAppendFormat:, and then procede to copy into it all of the thousands of characters you had already appended. This could easily result in an out of memory error, since the size of the temporary strings would be growing exponentially as you add more and more calls.

Using NSMutableString will not re-copy all of the string data when you call appendFormat:, since the mutable string maintains an internal buffer and simply tacks new strings on to the end of it. Depending on the size of your string, you may want to reserve a huge chunk of memory ahead of time (use a meaningful number for the ...WithCapacity: argument). But there is no need to go that route unless you actually run into performance issues.

like image 124
e.James Avatar answered Jan 20 '26 16:01

e.James


There are a few problems with your sample code:

  1. You should be using a NSMutableString to build up an output string by appending multiple parts. NSString is an immutable class which means that each time you call stringByAppendingFormat: you are incurring the overhead of creating an additional new NSString object which will need to be collected and released by the autorelease pool.

    NSMutableString * pageData = [NSMutableString stringWithCapacity:0];

  2. You should use appendString: on your NSMutableString to append content, instead of stringByAppendingFormat: or appendFormat:. The format methods are intended for creating new strings based on a format specifier which includes special fields as placeholders. See Formatting String Objects for more details. When you're using stringByAppendingFormat: with just a literal string like your code has, you are incurring the overhead of parsing the string for the non-existant placeholders, and more importantly, if the string happens to have a placeholder (or something that looks like one) in it, you'll end up with the EXEC_BAD_ACCESS crash that you are getting. Most likely this happening when your bodyText is appended. Thus if you simply want to append a '

    ' to your NSMutableString do something like this:

    [pageData appendString:@"<p>"];

  3. If you want to append the contents of the self.bodyText property to the string, you shouldn't put the name of the property inside of a string literal (i.e. @"self.bodyText" is the literal string "self.bodyText", not the contents of the property. Try:

    [pageData appendString:self.bodyText];

As an example, you could actually combine all three lines of your sample code by using a format specification:

pageData = [pageData stringByAppendingFormat:@"<p>%@</p>", self.bodyText];

In the format specification %@ is a placeholder that means insert the result of sending the description or descriptionWithLocale: message to the object. For an NSString this is simply the contents of the string.

like image 32
Jason Jenkins Avatar answered Jan 20 '26 17:01

Jason Jenkins



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!