0

我正在开发一个 iPad 应用程序,我在这里遇到了一个非常奇怪的问题。我会尽量解释清楚。

我有一个名为的类TranslationObject,它包含一个键和一个文本值。我创建了这个类,如下所示:

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

@property (nonatomic, retain) NSNumber *key;
@property (nonatomic, retain) NSString *value;

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

@end

将来翻译将从 XML 或 DB 中提取,但现在我执行以下操作:

@interface Translation : NSObject {
    NSMutableArray *m_extfeat;
}

@property (nonatomic, retain) NSMutableArray *extfeat;

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

@end

执行:

@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

这些翻译在 a 中使用UITableViewController并在方法中被获取viewDidLoad为:

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

我在它的 处使用这些值cellForRowAtIndexPath,在这里我调用一个方法来配置单元格:

- (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]);
}

正如上面的代码片段所说,奇怪的是,只有当 _data 数组包含超过 12 个项目时,应用程序才会在获取键值时崩溃。因此,如果我只用 12 个或更少的项目填充 _data 变量,我的代码就可以正常工作。如果我添加超过 12 个,应用程序会在获取第 13 个对象后立即崩溃。

所以我启用了 NSZombies,所以当我检查该方法中的第 13 项时,该仍然很好,但它只是变成 Zombie的键。再一次.. 仅从第 13 条开始!

有谁知道这怎么可能?是否可能存在最大数量的项目可以存储在内存中?第 12 项的内存是否已满?但如果是这样的话,那为什么价值仍然存在。怎么可能只是之前放出来的钥匙?!如何?!

我希望这个解释是有道理的,有人可以对这个案子有所了解.. =/

谢谢!

编辑:这是 TranslationObject 的 initWithKey 方法的实现:

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

    self = [super init];

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

回归自我;}

4

1 回答 1

1

确保您使用TranslationObject或保留数字中的属性访问器:

@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

规格:

self.key = key;

是调用属性访问器方法的语法;在这种情况下,设置访问器。鉴于您使用nonatomicretain属性声明了您的属性,如下所示:

@property (nonatomic, retain) NSNumber *key;

set 访问器看起来像

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

当您添加时,编译器会自动生成 set 访问器:

@synthesize key=_key;

相反,调用

_key = key;

只是将指针的值复制key到中_key,但不复制 所retain引用的对象keyTranslationObject不承担密钥的所有权。如果您不想使用访问器,正确的实现将是

_key = [key retain];
于 2011-07-22T20:50:49.840 回答