I am trying to check NSZombieEnabled is working in my code.
I've the following settings :
and I've the following code in didFinishLaunchingWithOptions
NSString *string = nil;
[string release];
string = #"abc";
but, there is no error generated. there is no notification from NSZombie as well. Should I do some more settings. Please help me, cause I've a lib that I've imported and there is a EXC_BAD_ACCESS with code 13 happening, and I am not able to get to the error cause.
The stack and the console looks like this
Your settings are correct, but your code does not create any zombies. A zombie is an object which has been freed, but is re-used. Something like this will create a zombie:
NSString* string = [NSString stringWithString:#"abc"];
[string release];
[string length];
In this example, the string is released, and then you attempt to use it by calling its length method.
In the case of your library, what does the stack look like when it gives you the EXC_BAD_ACCESS?
Related
I have an NSDragOperation that gets a property lists path upon the user dragging it into the window. That seems to work just fine, and I can save the path information to an NSString:
NString *thisPath = draggedFilePath;
NSLog(#" %#",thisPath);
output: 2014-02-09 09:19:46.072 app[5944:303] /Users/Me/Desktop/file.plist
The problem starts when I go into a dispatch queue. When I try and read the NSString from inside the background queue the output becomes NSPrincipalClass. Does anyone know why this is happening, or if I'm supposed to convert the NSString to some other format before entering dispatch_queue_t?
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue, ^{
for (NSUInteger i = 0; i < 1; i++) {
dispatch_async(dispatch_get_main_queue(), ^{
});
}
NSLog(#" %#",thisPath);
output: 2014-02-09 09:19:56.234 app[5944:12203] NSPrincipalClass
EDIT: the output of the string using NSLog inside dispatch queue turns up random symbols, and also crashes. The last output was <__NSMallocBlock__: 0x55a860> - I have other strings that seem to be just fine within the same function, so I really don't know what is causing this.
one of three things is happening...
it is being deallocated, and a new object is being allocated in its place... you can try zombies...
it is getting assigned to a garbage value ie. draggedFilePath isn't ever initialized to zero, and isn't set to a good value.
your stack is getting smashed and it just happens to be there when it crashes... this is the hardest to find.
you are going to have to turn on zombies, the exception breakpoint and just step through it in the debugger... if that fails you get to either run in instruments with the malloc tool or turn on malloc history logging.
Does it work if you prefix the declaration of thisPath with `__block'? Like this:
__block NString *thisPath = draggedFilePath;
I have this code snippet below. The purpose is to write the contents of an array to a plist file. When I run this I don´t get any errors and everything seems to be fine. The problem is that the file doesn´t appear on the desktop. I used writeToFile before in other projects without any problems. What is wrong with it? Greetings from Switzerland, Ronald Hofmann.
- (IBAction) doActionPlist: (NSButton *) sender
{
NSString *fileExt = #".plist";
NSArray *myResultArray = [NSArray arrayWithObjects:
#"Product Number Unlimited Desktop:",
#"4DDP120-UUS001-ANLKR-17C6B",
#"4DDP130-UUS001-ANQEI-1BC12",
#"4USE120-UUS001-80BY1-1EAB0",
#"4USE130-UUS001-6NTUE-11D64",
#"qA0iHnw4EIgOALgAAAQCmUtj",
#"qA0iHnw6EIgAALgAAPUBhByg",
#"4DDP11U00USN001",
#"4DDP13U12USN001",
#"4UCL00U00USN001",
#"4UCL00U00USN010",
#"4UCL11U00USN001",
#"4UCL11U00USN010",
#"4UCL12U11USN001",
#"4UCL12U11USN010",
#"4UCL13U12USN001",
#"4UCL13U12USN010",
#"4USE12U11USN002",
#"4USE13U12USN002",
#"4UWE13U12USN999",
nil];
NSString *thePath = [NSString stringWithFormat:#"/Users/ronny/Desktop/Testfile%#",fileExt] ;
[myResultArray writeToFile:thePath atomically:YES] ;
}
Unfortunately, it can be difficult to debug this call because it only returns YES or NO with no further information about why it succeeded or failed. The fact that it's not throwing any exceptions doesn't necessarily mean that nothing is going wrong; it just means that NSArray can't be bothered to tell you about it.
If you're really at wit's end, you might try converting your NSArray to NSData using NSPropertyListSerialization and then using writeToFile:options:error instead. If you do this, post the error message and someone should be able to offer better debugging advice.
I have a simple method run in background thread which open txt file and split it on lines. After that I'm trying to release memory, but something goes wrong. I'm using ARC. Here's code:
#autoreleasepool {
NSString* file = [NSString stringWithContentsOfFile:resourcePath encoding:NSWindowsCP1251StringEncoding error:&error];
NSArray* test = [file componentsSeparatedByString:#"\n"];
test = nil;
}
String released fine, but array still in memory. What I've missed?
UPD: Hm... Just tried to duplicate array few times, and after end of the method array really deallocates. But there is memory leak if I create this array. Where it could be?
// test = nil;
Dismiss it, and ARC will work fine.
I use this code in two different files to fill the categories array from a string of text from a text file, in which entries are separated by double pipes.
In the first file, my appViewController class, everything is fine. In the second, popoverViewController, the program bombs with EXC_BAD_ACCESS on the arrayWithArray: line. Declarations for categories, tempArray, diskfile, and textFromFile are the same in both interface files.
NSLog tracers and breakpoints confirmed values of variables are the same down to that last fatal line. The popover contains a picker, so picker delegate and datasource protocols are in place. That's the only difference. Can anyone explain what might be going on?
categories=[[NSMutableArray alloc] init];
tempArray = [[NSMutableArray alloc] init] ;
NSMutableString *textFromFile=[[NSString alloc] init];
NSString *filePath = [[NSBundle mainBundle] pathForResource: #"Categories" ofType: #"txt"];
if (filePath) {
textFromFile = [NSString stringWithContentsOfFile:filePath];
categories=[NSMutableArray arrayWithArray:[textFromFile componentsSeparatedByString: #"||"]];
}
Set NSZombieEnabled, MallocStackLogging, and guard malloc in the debugger. Then, when your App crashes, type this in the gdb console:
(gdb) info malloc-history 0x543216
Replace 0x543216 with the address of the object that caused the crash, and you will get a much more useful stack trace and it should help you pinpoint the exact line in your code that is causing the problem.
See this article for more detailed instructions.
I'm working through Cocoa smoothly, but this problem seems so basic it cancels out all the cool stuff I learned. :/
I have a generated file path, and it needs to be in NSURL format. From research, this is the code I wrote:
NSLog(#"Old path = %#", pathToFile);
NSURL *xmlURL = [[[NSURL alloc] init] fileURLWithPath:pathToFile];
NSLog(#"New path = %#", [xmlURL absoluteString]);
And the output:
2010-01-27 15:39:22.105 MusicLibraryStats[28574:a0f] Old path = file://localhost/Users/[username]/Music/iTunes/iTunes%20Music%20Library.xml
2010-01-27 15:39:22.105 MusicLibraryStats[28574:a0f] New path = (null)
First off, the alloc-init shouldn't even be necessary; other people seem to get away with it. In this case, if I don't alloc-init, I get an 'unrecognized selector' error on that line. Of course, now I'm just getting plain old (null).
Where did I goof?
Thanks!
The [[NSURL alloc] init] is not just unnecessary, it's invalid. fileURLWithPath: is a class method, which means you can only call it on the class object (that is, NSURL itself). It does not produce a compile error because -(NSURL *)init returns an object of type id, and does not result in a runtime error because -(NSURL *)init actually returns nil, and messages sent to nil will just cascade another nil as their return value.
This code should work:
NSString* pathToFile = #"/this/is/a/path";
NSURL* url = [NSURL fileURLWithPath:pathToFile];
I found your problem.
-[NSOpenPanel URLs] returns an array of NSURL objects, which you treat as NSString objects. That's not right. You should use the following:
NSURL* url = [[oPanel URLs] objectAtIndex:0];
The debugger could've show you that if you looked at the pathToFile variable. Make sure to check it next time. :) Hovering a variable with your mouse should get you its type.
However, remember that there are situations where you will legitimately encounter another type than the one you expected. For instance, the private NSPathStore2 class is part of the NSString cluster, and you can do everything NSString supports on NSPathStore2 objects. (If this happens and you're not too sure, check the documentation to see if the type you expect is a cluster type. That's how they're called in the documentation.)