开发者

Could there be an issue with the max. memory capacity? Or why is this variable partly released?

开发者 https://www.devze.com 2023-03-22 13:35 出处:网络
I\'m developing an iPad app and I ran into a really weird issue here. I\'ll try to explain it as good as possible.

I'm developing an iPad app and I ran into a really weird issue here. I'll try to explain it as good as possible.

I have a class named TranslationObject which is holding a key and a textual value. I have created this class as the following:

@interface TranslationObject : NSObject {
    NSNumber *_key;
    NSString *_value;
}

@property (nonatomic, retain)开发者_如何学Python NSNumber *key;
@property (nonatomic, retain) NSString *value;

- (id) initWithKey:(NSNumber *) key andValue:(NSString *) value;

@end

The translations will be pulled from a XML or DB in the future, but for now I do the following:

@interface Translation : NSObject {
    NSMutableArray *m_extfeat;
}

@property (nonatomic, retain) NSMutableArray *extfeat;

+ (Translation *) getInstance;
- (id) init;
- (NSMutableArray *) getExtFeat;

@end

Implementation:

@implementation Translation

@synthesize extfeat = m_extfeat;

- (id) init {
    self = [super init];

    if (self) {
        m_extfeat = [[self getExtFeat] retain];
    }
    return self;
}

- (NSMutableArray *) getExtFeat {
    TranslationObject *obj1 = [[[TranslationObject alloc] initWithKey:[NSNumber numberWithInt: 0] andValue:@"Animal house"] autorelease];

    .... more items declared ....

    NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11, obj12, obj13, obj14, obj15, obj16, obj17, nil];

    return [array autorelease];
}
@end

These translations are being used in a UITableViewController and are being fetched in the viewDidLoad method as:

- (void)viewDidLoad
{
     _data = [[Translation getInstance].extfeat retain];
}

I use these values at its cellForRowAtIndexPath, where I call a method to configure the cell:

- (void) configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *) indexPath {
    TranslationObject *object = (TranslationObject *) [_data objectAtIndex:indexPath.row];

    //Crashes here at 13th item:
    NSLog("Object key: %@", [object.key stringValue]);
}

As the snippet above says, strangely, the app crashes when fetching the key value only if the _data array contains more than 12 items. So if I only fill the _data variable with 12 items or less, my code works fine. If I add more than 12, the app crashes as soon as it fetches the 13th object.

So I enabled NSZombies and so when I check the 13th item in that method, the value is still fine, but it's only the key that turned into a Zombie. And again.. Only from the 13th item on!

Does anyone know how this is possible? Is it maybe so that there is a maximum number of items that can be stored in the memory? Is the memory full at the 12 item? But if that'd be the case, then why would the value still be there. How would it be possible that it's just the key that is being released before?! And how?!

I hope this explanation makes sense and someone can shine a light over this case.. =/

Thanks!

EDIT: Here's the implementation of the initWithKey method of the TranslationObject:

- (id) initWithKey:(NSNumber *) key andValue:(NSString *) value {

    self = [super init];

    if (self) {
        _key = key;
        _value = value;
    }

return self; }


Make sure your using the property accessors in the TranslationObject or retaining the number:

@implementation TranslationObject

@synthesize key=_key, value=_value;

- (id) initWithKey:(NSNumber *) key andValue:(NSString *) value {
    self = [super init];
    if (!self) return nil;

    self.key = key;  // ensures key is retained
    self.value = value;

    return self;
}

…

@end

Specifics:

self.key = key;

is the syntax for calling the accessor methods for the property; in this case the set accessor. Given you declared your property with the nonatomic and retain attributes as follows:

@property (nonatomic, retain) NSNumber *key;

the set accessor will look something like

- (void)setKey:(NSNumber *)value {
    if (value != _key) {
        id old = _key;
        [value retain];
        _key = value
        [old release];
    }
}

The set accessor is automatically generated by the compiler when you added:

@synthesize key=_key;

Conversely, calling

_key = key;

simply copies the value of the pointer in key to _key, but does not retain the object referred to by key. TranslationObject does not assume ownership of key. If you did not want to use the accessor, the correct implementation would be

_key = [key retain];
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号