This is the reason for my confusion:
NSString *path = [self.dataPath stringByAppendingPathComponent:@"dummy.plist"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
NSString *dummyKeyValue = [dict valueForKey:@"dummyKey"];
// NSLog(@"%@",[NSString stringWithString:dummyKeyValue]);
[dict release];
NSString *anotherString = [dummyKeyValue lowercaseString];
This code triggers the EXC_BAD_ACCESS error in the last line. It seems that it is because NSDictionary publishes its key value. I don’t understand why the dummyKeyValue definition is not considered, Because obviously dummyKeyValue still points to the value of “dummyKey”.
Now, when you comment out the NSLog line, the next problem and even more interesting phenomenon appears. Using dummyKeyValue in a certain way seems to prevent release The memory it points to. Why?
Thanks for the help!
If you want to keep a strong reference to the dummyKeyValue, you need to keep it after receiving it. Of course, this also means you need to release it when you are done. Try this:
p>
NSString *dummyKeyValue = [[[dict valueForKey:@"dummyKey"] retain] autorelease];
Now, dummyKeyValue will always exist until it is automatically released The pool scope ends. Usually, before the return value, an accessor method is written to do this to avoid the situation you are seeing.
It is worth noting that if you use ARC (Automatic Reference Counting) , You will not encounter this problem, because the compiler will insert the necessary retain/release calls to ensure that the dummyKeyValue is always there until you are done.
I am currently trying Enter iOS development by myself. Now I can’t understand memory management.
This is the reason for my confusion:
NSString *path = [self.dataPath stringByAppendingPathComponent:@ "dummy.plist"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
NSString *dummyKeyValue = [dict valueForKey:@"dummyKey"];
// NSLog(@"%@",[NSString stringWithString:dummyKeyValue]);
[dict release];
NSString *anotherString = [dummyKeyValue lowercaseString] ;
This code triggers the EXC_BAD_ACCESS error in the last line. It seems that it is because NSDictionary publishes its key value. I don’t understand why the dummyKeyValue definition is not considered, because obviously dummyKeyValue still points to the value of “dummyKey”.
p>
Now, when you comment out the NSLog line, the next question and even more interesting phenomenon appears. Using dummyKeyValue in a certain way seems to prevent the memory it points to from being released. Why?
Thanks for the help!
In manual reference counting mode, simply defining a variable does not mean that the object pointed to by the variable will be automatically retained. When the dict is released, it will be released Its value objects, if no other objects strongly refer to them (i.e. their reference count is now 0), they will be released. This is what you see here.
If you To keep a strong reference to the dummyKeyValue, you need to keep it after receiving it. Of course, this also means you need to release it when you are done. Try this:
NSString *dummyKeyValue = [[[dict valueForKey:@"dummyKey"] retain] autorelease];
Now, dummyKeyValue will always exist until the end of the current autorelease pool range. Usually, before the return value, will Write an accessor method to do this to avoid the situation you are seeing.
It is worth noting that if you use ARC (Automatic Reference Counting), you will not encounter this problem because the compilation The device will insert the necessary hold/release calls to ensure that the dummyKeyValue will exist until you are done.