简体   繁体   中英

Strange BAD_ACCESS exception iOS

I have a property (noARC)

@property (nonatomic, retain) NSString *itemUUID;

and an initialization

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    if (_itemUUID) {
        [self updateViews];
    } else {
       _itemUUID = [[EADataManager sharedInstance] generateUuidString];
        NSLog(@"%@", _itemUUID);
    }
}

The UUID generation method is

- (NSString *)generateUuidString
{
    CFUUIDRef UUID = CFUUIDCreate(kCFAllocatorDefault);
    NSString *uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, UUID);
    [uuidString autorelease];
    CFRelease(UUID);
    return uuidString;
}

and I try to use this property in a very simple way in another method:

- (IBAction)submitButton:(id)sender
{
    if ([nameField.text length] > 3)
    {
        NSLog(@"%@", _itemUUID);
        NSDictionary *changedData = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:nameField.text, priceField.text, quantityField.text, nil] forKeys:[NSArray arrayWithObjects: @"Name", @"Price", @"Quantity", @"UUID", nil]];
    }
}

So on the second NSLog there is an exception BAD_ACCESS . Can't understand my fault.

Your generateUuidString is returning an autorelease value, so your viewDidAppear should retain it (which you can do by using the setter, self.itemUUID = ... ).

And kambala is correct as well, that you've also added three objects for your four keys of your dictionary.

You forgot to add your UUID to the object list in the dictionary, so number of objects and keys mismatches. Correct dictionary initialization:

NSDictionary *changedData = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:nameField.text, priceField.text, quantityField.text, _itemUUID, nil] forKeys:[NSArray arrayWithObjects: @"Name", @"Price", @"Quantity", @"UUID", nil]];

If you are not using ARC, this

_itemUUID = [[EADataManager sharedInstance] generateUuidString];

is wrong, it assigns an object you do not own to an instance variable. That object will go away when the autorelease pool is drained. Since you have declared a property, you should use it.

[self setItemUUID: [[EADataManager sharedInstance] generateUuidString]];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM