NSMutableArray计数不断变化

时间:2011-03-16 23:35:30

标签: iphone objective-c class nsmutablearray

我有太多的代码知道我需要在这里引用,但在我的app委托中我有一个NSMutableArray。然后在另一个类中,它创建了一个NSMutableArray的新条目,但在传递回另一个应该使用它来在屏幕上显示内容的类时,它不会显示任何内容。在创建它的类的末尾放置一个NSLog用于NSMutableArray计数显示数字1,然后将相同的NSLog代码放在要使用的类的开头,返回0。

为什么会这样?

编辑:好的,我会尝试包含所有相关的代码..

app delegate.h:

@interface palettesAppDelegate : NSObject <UIApplicationDelegate> {
 NSMutableArray *colourPalettesContainer;

}
@property (assign, readwrite) NSMutableArray *colourPalettesContainer;
@end

app delegate.m:

#import "palettesAppDelegate.h"

@implementation palettesAppDelegate

@synthesize colourPalettesContainer;

- (void)dealloc {
    [colourPalettesContainer release];
    [super dealloc];
}


@end

Homeview.h:

#import <UIKit/UIKit.h>
#import "HandlingPalettes.h"

@interface HomeView : UIViewController {

    HandlingPalettes *handlingPalettes;

}


@end

Homeview.m:

#import "HomeView.h"
#import <QuartzCore/QuartzCore.h>


@implementation HomeView


- (void)viewDidLoad {
    [super viewDidLoad];
handlingPalettes = [[HandlingPalettes alloc] init];

    [handlingPalettes newPalette];

}

-(void)viewWillAppear:(BOOL)animated {


    NSLog(@"view will appear: %i", [dataCenter.colourPalettesContainer count]);
    int numberOfExisting = [dataCenter.colourPalettesContainer count];

}

- (void)dealloc {
    [handlingPalettes release];
    [super dealloc];
}


@end

HandlingPalettes.h:

#import <UIKit/UIKit.h>

@interface HandlingPalettes : UIViewController {

}


-(void)newPalette;



@end

HandlingPalettes.m:

#import "HandlingPalettes.h"
#import "HomeView.h"
#import "palettesAppDelegate.h"



@implementation HandlingPalettes


-(void)newPalette {

    palettesAppDelegate *dataCenter = (palettesAppDelegate *)[[UIApplication sharedApplication] delegate];

    //If this is the first palette
    if (dataCenter.colourPalettesContainer == nil) {
    dataCenter.colourPalettesContainer = [[NSMutableArray alloc] init];
    }
    //Add a new palette

        [dataCenter.colourPalettesContainer addObject:@"Test1", @"Test2", nil];


    NSLog(@"Handling:    %i", [dataCenter.colourPalettesContainer count]);


}- (void)dealloc {
   [super dealloc];
}


@end

3 个答案:

答案 0 :(得分:1)

你的主要mutablearray在你的app代表中。那么,看看如果在每种方法中你想要访问数组你会有一行来设置app委托关系会发生什么

    palettesAppDelegate *dataCenter = (palettesAppDelegate *)[[UIApplication sharedApplication] delegate];

现在,当您调用dataCenter对象时,您将引用App Delegate,您的程序将找到该阵列。

您可能还会发现,每个要引用App Delegate的对象都需要#import "palettesAppDelegate.h"

请注意,从架构的角度来看,仅添加应用委托代码不一定是处理此问题的正确方法。但如果它有效,你至少知道你原来问题的答案。

答案 1 :(得分:1)

我倾向于摆脱newPalette方法,而是在app delegate中为colourPalettesContainer创建一个getter方法。 即:

appdelegate.h

@interface PalettesAppDelegate : NSObject <UIApplicationDelegate> {
   NSMutableArray *colourPalettesContainer;

} 
@property (non-atomic, retain) NSMutableArray *colourPalettesContainer;
@end

@implementation palettesAppDelegate

appdelegate.m

#import "appdelegate.h"
@synthesize colourPalettesContainer;
- (NSMutableArray *) colourPalettesContainer{
    if(colourPalettesContainer==nil){
        colourPalettesContainer=[[NSMutableArray alloc] init];
    }
    return colourPalettesContainer;
}
- (void)dealloc {
    [colourPalettesContainer release];
    [super dealloc];
}
@end

然后您应该可以通过调用

来添加项目
[appDelegate.colourPalettesContainer addObject:object];

答案 2 :(得分:1)

我怀疑问题最终与colourPalettesContainer成员的混乱内存管理有关。您在app delegate的dealloc方法中释放它,但该类永远不会保留它!如果你遵循Apple的memory management guidelines,它会更加清晰:你的类应该只释放它们拥有的对象(即它们自己之前保留的对象)。例如,您可以通过声明数组的属性retain来执行此操作:

@property (retain) NSMutableArray *colourPalettesContainer;

(为防止数组泄漏,您还需要在newPalette方法中释放或自动释放它。保留和释放应始终紧密配对。)

但更好的是,为什么不简单地在app delegate的init方法或其访问器中创建数组(如果由于某种原因你只想在第一次使用时继续创建它)?除非您想一次替换所有调色板,否则没有理由让数组从app delegate外部分配。

@interface PalettesAppDelegate : NSObject <UIApplicationDelegate> {
@private
    NSMutableArray *colourPalettesContainer;
}
@property (readonly) NSMutableArray *colourPalettesContainer;
@end

@implementation PalettesAppDelegate

- (NSMutableArray *)colourPalettesContainer {
    if (colourPalettesContainer == nil) {
        colourPalettesContainer = [[NSMutableArray alloc] init];
    return colourPalettesContainer;
}

- (void)dealloc {
    [colourPalettesContainer release];
    [super dealloc];
}
@end

要使设计更清晰,请将colourPalettesContainer属性的类型更改为NSArray *,并向应用代理添加-addPalette:方法。 (在类中公开暴露可变数组并不是一个好主意。)然后,您可以简单地删除-newPalette中的HandlingPalettes。 (如果你想在HandlingPalettes中使用所有的调色板处理方法,那么只需将数组移动到那里。如果你需要从你应用中的随机位置访问调色板,那么你可以简单地将保留的引用放到你的app委托中的HandlingPalettes对象。)

一旦你清理了对象所有权混乱,计数不匹配将“通过魔法”自行解决,或者原因可能会变得更加明显。在后一种情况下,请检查HomeView的{​​{1}}实际上是否与dataCenter中的对象相同。 (您省略了HandlingPalettes如何获取其引用 - 您确定不是偶然创建应用委托的另一个实例吗?)

(顺便说一句,您可能打算在HomeView中使用-addObjects:,而不是-addObject:。请注意,所有类名都应大写,没有例外:即始终使用newPalette,永远不会PalettesAppDelegate。如果出于某种原因,Xcode的项目模板就是这样创建的,只需重命名该类。小写的类名很容易与变量名混淆。另外,试着找到更好的名字一般来说:例如,代替palettesAppDelegate,我会使用HandlingPalettes(以反映它是UIViewController的子类);而不是PalettesViewController,我宁愿只是选择dataCenter。)