如何正确保留NSArray或基本使用

时间:2011-07-06 18:52:29

标签: iphone objective-c ios xcode

我有一个nsarray,当我从我的一个方法NSLog它我可以看到它的内容,但当我试图从其他地方看它内部它似乎是空的。我知道我的记忆管理需要一些工作,任何人都可以帮助解释这里发生的事情吗?

新代码

WorkOutList.h

#import <UIKit/UIKit.h>


@interface WorkOutList : UIViewController {

    NSManagedObjectContext *managedObjectContext;
    NSMutableArray *customWorkouts;
    NSArray *passedWorkout;
}

@property(nonatomic, retain)NSManagedObjectContext *managedObjectContext;
@property(nonatomic, retain)NSMutableArray *customWorkouts;
@property(nonatomic, retain)NSArray *passedWorkout;

-(IBAction)customWorkouts:(id)sender;

-(void)passWorkoutBack:(NSArray *)workout;


@end

WorkOutList.m

@implementation WorkOutList

@synthesize managedObjectContext, customWorkouts, passedWorkout;

- (void)viewDidLoad {
    [self setupContext];
    NSLog(@"View Did Load");
    customWorkouts = [[NSMutableArray alloc] init];
    passedWorkout = [[NSArray alloc] init];
    [super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self fetchWorkoutList];
    NSLog(@"View will Appear");
    NSLog(@"Array from View Will Appear : %@", passedWorkout);

}

-(IBAction)customWorkouts:(id)sender{
    CoCoachAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    SelectedWorkout *selectedWorkout = [[SelectedWorkout alloc] initWithStyle:UITableViewStyleGrouped];

    [selectedWorkout recieveNeededData:customWorkouts];

    [appDelegate.practiceNavController pushViewController:selectedWorkout animated:YES];
    [selectedWorkout release];
}

-(void)passWorkoutBack:(NSArray *)workout{
    passedWorkout = workout;
    [passedWorkout retain];
}

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

SelectedWorkout.h

#import <UIKit/UIKit.h>


@interface SelectedWorkout : UITableViewController {


    NSMutableArray *workoutListForTable;
}

@property(nonatomic,retain)NSMutableArray *workoutListForTable;

-(void)recieveNeededData:(NSMutableArray *)workoutList;

@end

SelectedWorkout.m (除了设置tableView的所有内容)

    @implementation SelectedWorkout

    @synthesize workoutListForTable;

    -(void)recieveNeededData:(NSMutableArray *)workoutList{

        if (workoutListForTable != workoutList) {
            workoutListForTable = workoutList;  
        }

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        [tableView deselectRowAtIndexPath:indexPath animated:YES];

        CoCoachAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
        WorkOutList *workoutListView = [[WorkOutList alloc]init];

        [workoutListView passWorkoutBack:[workoutListForTable objectAtIndex:indexPath.row]];
        [appDelegate.practiceNavController popViewControllerAnimated:YES];
    }

    - (void)dealloc {

        [workoutListForTable release];
        [super dealloc];
    }


    NSLog(@"other table : %@", workoutListForTable);
    [workoutListForTable retain];
}

3 个答案:

答案 0 :(得分:3)

你的内存管理很好,虽然有点尴尬 - 你可以声明一个保留属性并避免底部的retain。你的问题来自于'viewWillAppear:'在'passWorkoutBack:'之前被调用的事实,所以它在2处是空白的,因为2在1之前被调用。如果你期望某事在2,那么你的'fetchWorkoutList'方法不是工作正常。

答案 1 :(得分:2)

你的setter方法应该释放前一个值并保留新值,例如

– (void)passWorkoutBack:(NSArray *)workout {

    if (passedWorkout != workout) {

        [passedWorkout release];

        passedWorkout = [workout retain]; 

    }

}

此处,if语句可确保您在保留之前不会意外释放workout

最后,由于您在alloc中致电viewDidLoad,您应该在viewDidUnload中调用release


由于您在alloc中呼叫initviewDidLoad,因此调用此方法时,passedWorkout可能具有的任何值都将被删除。如果您希望保留其值,即使视图已卸载并重新加载,那么您应该在ViewController的passedWorkout方法中分配init,当然,也可以在dealloc中释放它方法。

答案 2 :(得分:0)

我认为这是您对应用流程的理解:

  1. passWorkoutBack为您的视图控制器提供一个NSArray,它放在'passedWorkout'中。
  2. 调用viewDidLoad并将'passWorkout'重新初始化为空数组。
  3. 调用viewWillAppear,你意识到你的数组是空的。
  4. 说实话,我认为这是因为缺乏对设计健壮代码的理解(不用担心,这是编程中最难学的东西)。以下是一些我认为会使这款应用流程更顺畅的提示:

    1. 为viewController类创建一个新的init方法,并在其中包含一个参数,以传递此锻炼数组。
    2. 如果你从某个地方得到一个数组,你需要做的就是保留它(通过使用Inspire48所说的属性,或者像你已经完成的那样调用对象上的retain),你甚至不需要在你从任何地方获得它之前分配或初始化数组。
    3. 了解viewController生命周期。你知道viewDidLoad和viewWillAppear之间的区别吗?如果你不这样做,请学习,因为如果使用得当它们都是好工具。
    4. Anywho,我希望这有所帮助,而且我不太'preachy'。我假设你的应用程序和你很多,所以纠正我的错误。欢呼声。