我创建了一个具有静态NSMutableArray的类,我希望在我覆盖init
期间填充该类的每个实例,所以我不需要做任何比我更多的编码需要。
我应该指出数组工作正常,我只是在存储正确的数据时遇到了问题。
这有意义吗?如果是这样我怎么能这样做?
虽然我尝试过这样做
_instance = self;
[[MyClass getStack] addObject:_instance];
似乎我无法访问该属性的实例,并且在记录时我得到的是:
2012-07-14 22:37:58.223 Application[4497:1bb03] <MyClass: 0x92cfc70>
使用更多代码进行修改:
我的.h文件:
@interface MyClass : NSObject
+ (NSMutableArray *)getStack;
我的.m文件:
@interface MyClass ()
@end
static NSMutableArray *stack;
@implementation MyClass
使用崩溃图像进行编辑
记录数组属性时NSLog(@"%@", [[[MyClass stack] objectAtIndex:0] adam]);
它在该行崩溃并给出以下错误。
答案 0 :(得分:1)
一种方法是将每个实例包装在NSValue中。 NSValue有一个名为-valueWithNonretainedObject:
的方法,它可以完成它的声音。它创建一个NSValue实例,该实例包含一个对象但不保留该对象。现在,当您将NSValue实例添加到数组时,该数组将保留NSValue实例,而不是包含的对象,并且不会阻止实例被释放。这是代码中的一个例子:
static NSMutableArray *instanceArray = nil;
@implementation MyClass
+ (void)addInstance:(MyClass *)instance
{
if (!instanceArray) instanceArray = [[NSMutableArray alloc] init];
NSValue *value = [NSValue valueWithNonretainedObject:instance];
[instanceArray addObject:value];
}
+ (void)removeInstance:(MyClass *)instance
{
NSValue *valueToRemove = nil;
for (NSValue *value in instanceArray)
{
if ([value nonretainedObjectValue] == instance)
{
valueToRemove = value;
break;
}
}
if (valueToRemove != nil) [instanceArray removeObject:valueToRemove];
}
- (id)init
{
self = [super init];
if (self != nil)
{
[[self class] addInstance:self];
}
}
- (void)dealloc
{
[[self class] removeInstance:self];
[super dealloc];
}
@end
答案 1 :(得分:0)
编辑:正如已经正确指出的那样,Objective-C容器存在过度保留问题。此外,不保证可以使用自动释放池,因此必须明确分配。
解决这些问题的方法是使用一个根本不保留的容器,例如:一个动态重新分配的数组或(如果是Objective-C ++)一个std::set< YourClass* >
,它包含指向当前实例的指针。
鉴于这种“安全”容器,基本思想保持不变:正常的初始化程序添加到容器中,例如myGlobal.insert(self);
,dealloc
方法将其删除,例如myGlobal.erase(self);
。
答案 2 :(得分:0)
将init
中的每个实例添加到全局数组中很容易:
static NSMutableArray *stack = nil;
@implementation MyClass
+ (void)initialize {
if (stack == nil)
stack = [[NSMutableArray alloc] init];
}
+ (id)init {
self = [super init];
if (self) {
[stack addObject:self];
}
return self;
}
@end
您的问题必须来自其他方面。要么你没有保留全局数组。或者您没有正确存储您的“财产”(例如,您没有保留它)。或者其他什么。
答案 3 :(得分:0)
事实证明问题在于我创建的实例属性的名称,例如我为'size'创建了一个int,为'layer'创建了一个CALayer,但是这些被标准属性覆盖了。为了克服它,我只是将类名作为前缀添加到每个属性中。此外,由于格式为%@而不是%i,因此日志崩溃。谢谢大家的帮助!