0

New here (this forum and Xcode in general), so bear with me.

I've spent multiple hours off and on over the last severals days trying to track down what exactly that I'm doing wrong here, but I just don't seem to be able to pinpoint my issue.

Here's the relevant sections of my code (I believe).

In the header:

@interface BlahViewController : UIViewController {

  NSMutableString *display;

}

@property (nonatomic, retain) NSMutableString *display;

In the main:

@implementation BlahViewController

@synthesize display;

- (void)viewDidLoad {
    self.display = [[NSMutableString alloc] init];  
}

- (void)anotherFunction:(UIButton *)sender {

    NSString *info = [[sender titleLabel] text];

    [self.display appendString:info];
}

I run the code, press the UIButton, and I get an error. Here's the initial throw:

  *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM appendString:]: unrecognized selector sent to instance 0x4e3d300' ***

Thanks!

EDIT: The whole stack trace was requested, so here it is (after reviewing the stack I realize there may be confusion, I'm writing a very basic calculator currently, so the ViewController, etc, should consider that backdrop and "anotherFunction" = "digitPressed" in this particular case):

* Call stack at first throw: (

0 CoreFoundation 0x00e345a9 exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f88313 objc_exception_throw + 44
2 CoreFoundation 0x00e360bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00da5966 __forwarding
+ 966
4 CoreFoundation 0x00da5522 _CF_forwarding_prep_0 + 50
5 Calculator 0x0000273b -[CalculatorViewController digitPressed:] + 113
6 UIKit 0x002bb4fd -[UIApplication sendAction:to:from:forEvent:] + 119
7 UIKit 0x0034b799 -[UIControl sendAction:to:forEvent:] + 67
8 UIKit 0x0034dc2b -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
9 UIKit 0x0034c7d8 -[UIControl touchesEnded:withEvent:] + 458
10 UIKit 0x002dfded -[UIWindow _sendTouchesForEvent:] + 567
11 UIKit 0x002c0c37 -[UIApplication sendEvent:] + 447
12 UIKit 0x002c5f2e _UIApplicationHandleEvent + 7576
13 GraphicsServices 0x01723992 PurpleEventCallback + 1550
14 CoreFoundation 0x00e15944 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 52
15 CoreFoundation 0x00d75cf7 __CFRunLoopDoSource1 + 215
16 CoreFoundation 0x00d72f83 __CFRunLoopRun + 979
17 CoreFoundation 0x00d72840 CFRunLoopRunSpecific + 208
18 CoreFoundation 0x00d72761 CFRunLoopRunInMode + 97
19 GraphicsServices 0x017221c4 GSEventRunModal + 217
20 GraphicsServices 0x01722289 GSEventRun + 115
21 UIKit 0x002c9c93 UIApplicationMain + 1160
22 Calculator 0x00002254 main + 102
23 Calculator 0x000021e5 start + 53
)
terminate called after throwing an instance of 'NSException'
Current language: auto; currently objective-c

Meshach
  • 315
  • 1
  • 2
  • 16
  • The 'self.display = [[NSMutableString alloc] init];' line is a memory leak. You should instead use `self.display = [[[NSMutableString alloc] init] autorelease];` or `self.display = [NSMutableString string];` – romrom Jun 20 '11 at 18:42
  • Is it a memory leak if I release it in my viewDidUnload method? Because the way it's arranged now is that the -viewDidLoad alloc/inits and the -viewDidUnload releases. – Meshach Jun 20 '11 at 19:03
  • 'display' is a property with _retain_ memory management. So when you do `self.display = [[NSMutableString alloc] init];` it is strictly equivalent to `[display release]; display = [[[NSMutableString alloc] init] retain];` and you have a retain count of 2. If you have `self.display = nil` in you viewDidUnload method, you're decreasing the retain count by one, so there is still some memory allocated for the string but no way to access it anymore. It's a leak. – romrom Jun 21 '11 at 07:00

1 Answers1

1

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM appendString:]: unrecognized selector sent to instance 0x4e3d300' *

This indicates that you are calling appendString: an instance of some kind of NSArray, which obviously won't work.

Assuming that [self.display appendString:info]; is the actual source of the exception, then it is happening because self.display has likely been over-released and, coincidentally, an NSArray instance was allocated at the same place in memory.

You could use zombie detection to debug this.

Alternatively, you might be corrupting memory somewhere. Or, maybe, there is another assignment to display.

In any case, whenever you have a crash, there will be a backtrace. Please post it. There is the off chance that the crash is happening somewhere else.


5 Calculator 0x0000273b -[CalculatorViewController digitPressed:] + 113

Show the source to your digitPressed: method.


self.display = [[NSMutableString alloc] init];  

That is a memory leak; it'll be retained twice. Just do self.display = [NSMutableString string]; and self.display = nil; (in your viewDidUnload).

But that isn't the source of your problem; something is resetting the display variable or it is being over-released. Show all uses of display.

bbum
  • 162,346
  • 23
  • 271
  • 359
  • The error is occurring at the line you indicated. The stack trace is provided in the edits. – Meshach Jun 20 '11 at 17:52
  • Try changing the name of the NSMutableString and see if that helps. – Emil Jun 20 '11 at 17:54
  • Why would changing the name of the mutable string help?! The error message is clear as to what is happening and the backtrace shows that it is going off the rails in `digitPressed:`. – bbum Jun 20 '11 at 18:20
  • Not sure if you caught it bbum, but the "digitPressed" method is actually the method in question here. anotherFunction = digitPressed. – Meshach Jun 20 '11 at 18:55
  • Nope -- didn't catch that. Not sure why anyone would think a rename is going to help when execution is clearly crashing on that one line [as the backtrace indicates]. – bbum Jun 20 '11 at 19:32
  • .... I just caught it, I can't believe I didn't notice this before. It was in one of the loops, I was reassigning it to an NSMutableArray. Purely by accident. Wow. How did I not notice that. Well, thanks for your impervious logic bbum. It's incredibly appreciated. – Meshach Jun 20 '11 at 20:44
  • Glad you found the problem! When relatively new, it is easy to fall in the trap of randomly changing stuff in hopes that it fixes the problem. One of the challenges is learning to sift through the oft massive amount of spew / evidence related to a crash to find the signal that identifies the actual problem. It takes practice. – bbum Jun 20 '11 at 21:00