我的变量不断失去其价值

发布于 2024-12-28 04:27:05 字数 9441 浏览 4 评论 0原文

对 Objective-C 和 Xcode 非常陌生,我通过修改 DrillDownApp 教程来适应一个简单的项目,我在其中深入了解类别表、主题表、报价表,最后是报价详细信息视图。

我使用“CurrentLevel”变量来确定我处于上述哪个级别,但是在完成一次课程后,CurrentLevel 似乎重置为零。这是在 didSelectRowAtIndexPath 方法之后。

我确信它非常简单,只需要一些帮助即可找到它。我在下面发布了整个课程:

//
//  RootViewController.m
//  DrillDownApp
//
//  Created by iPhone SDK Articles on 3/8/09.
//  Copyright www.iPhoneSDKArticles.com 2009. 
//

#import "RootViewController.h"
#import "DrillDownAppAppDelegate.h"
#import "DetailViewController.h"
#import "Subject.h"
#import "Quote.h"
#import "QuoteMap.h"

@implementation RootViewController

@synthesize tableDataSource, CurrentTitle, CurrentLevel;
@synthesize subjects;
@synthesize quotes;
@synthesize quoteMap;
@synthesize categories;
@synthesize subject_id;
@synthesize subject;
@synthesize category;



- (void)viewDidLoad {
    [super viewDidLoad];
    // Uncomment the following line to add the Edit button to the navigation bar.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

    if(CurrentLevel == 0) {

        //Initialize our table data source
        NSMutableArray *tempArray = [[NSMutableArray alloc] init];
        self.tableDataSource = tempArray;
        [tempArray release];

        // create array that will store the data

        DrillDownAppAppDelegate *appDelegate = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
        self.tableDataSource = [appDelegate categories];
        self.subjects = [appDelegate subjects];
        self.quotes = [appDelegate quotes];
        self.quoteMap = [appDelegate quoteMap];

        NSLog(@"  TableDataSource Count:  %i", self.tableDataSource.count);

        self.navigationItem.title = @"Category";
    }
    else if (CurrentLevel==1) {
        self.navigationItem.title = @"Subject";
        self.title = @"Subject";
    }else if (CurrentLevel==2){
        self.navigationItem.title = @"Quote";
        self.title = @"Quote";
    }else{
        self.navigationItem.title = @"Detail";
        self.title = @"Detail";
    }

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }


    if(CurrentLevel==0){
        NSLog(@"//////   CURRENT LEVEL = 0      LOADING CATEGORIES INTO TABLE...");
        if(self.tableDataSource.count>0){
            Category *cat = [self.tableDataSource objectAtIndex:indexPath.row];
            NSLog(@"         category title = %@", cat.title);
           cell.textLabel.text = cat.title;
        } else {
            NSLog(@"      ERROR: self.tableDataSource has no objects in it!!!!");
        }
    } 
    else if(CurrentLevel==1){
        NSLog(@"//////   CURRENT LEVEL = 1      LOADING SUBJECTS INTO TABLE...");
        if(self.tableDataSource.count>0){
            Subject *sub = [self.tableDataSource objectAtIndex:indexPath.row];
            NSLog(@"         subject title = %@", sub.title);
            cell.textLabel.text = sub.title;
        }
    }
    else if(CurrentLevel==2){
        NSLog(@"//////   CURRENT LEVEL = 2      LOADING QUOTES INTO TABLE...");
        if(self.tableDataSource.count>0){
            Quote *q = [self.quotes objectAtIndex:indexPath.row];
            NSLog(@"         Quote title = %@", q.title);
            cell.textLabel.text = q.title;
        }
    }

    return cell;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    if(CurrentLevel==0){

        DrillDownAppAppDelegate *appDelegate = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
        NSUInteger count = [appDelegate.categories count];
        NSLog(@"Count of records in categories array: %i", count);

        return appDelegate.categories.count;

    }else if(CurrentLevel==1){

        NSUInteger count = [self.tableDataSource count];
        NSLog(@"Count of records in categories array: %i", count);

        return self.tableDataSource.count;    

    }else if(CurrentLevel==2){

        NSUInteger count = [self.quotes count];
        NSLog(@"Count of records in quotes array: %i", count);

        return self.quotes.count;    

    }else{

        return 1;

    }

}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}

#pragma mark Table view methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    //Prepare to tableview.
    RootViewController *rvController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle]];

    NSLog(@"self.CurrentLevel=   %i", self.CurrentLevel);


    if (CurrentLevel==2){


        //Set the title;
        rvController.CurrentTitle = @"Quote";

        //Push the new table view on the stack
        [self.navigationController pushViewController:rvController animated:YES];

        //      rvController.tableDataSource = tempArray;

        //Increment the Current View
        CurrentLevel = CurrentLevel + 1;
        NSLog(@"             CurrentLevel = %i", CurrentLevel);
        [rvController release];


    } else if (CurrentLevel==1) {

        DrillDownAppAppDelegate *appDelegate = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
        self.quotes = [appDelegate quotes];
        self.quoteMap = [appDelegate quoteMap];

        //Get the selected data source.
        Subject *cat = [self.tableDataSource objectAtIndex:indexPath.row];

        //Get the children of the present item.
        NSLog(@"subject_id selected was: %@", cat.subject_id);

        //get the quote_ids from quote_map for this subject_id
        NSPredicate *filterSubjectId = [NSPredicate predicateWithFormat:@"subject_id == %@", cat.subject_id];
        NSArray *quoteMapSection = [self.quoteMap filteredArrayUsingPredicate:filterSubjectId];
        NSLog(@"Count of quoteMapSections = %i", quoteMapSection.count);

        //loop through quote array and create a new array with matching quote_ids
        // TAKE THE QUOTE_ID AND USE INDEXOFOBJECT METHOD TO GRAB QUOTE OBJECT, THEN ADD IT TO THE NEW ARRAY

        QuoteMap *q = [quoteMapSection objectAtIndex:0];
        NSLog(@"   FIRST QUOTEMAP:  %@", q.quote_id);

        NSMutableArray *tempArray = [[NSMutableArray alloc] init];

        for (QuoteMap *qm in quoteMapSection){

            NSLog(@"quote_id=%@",qm.quote_id );
            //use predicate to filter out just the one I want
            NSPredicate *f = [NSPredicate predicateWithFormat:@"quote_id == %@", qm.quote_id];
            NSArray *quoteFiltered = [self.quotes filteredArrayUsingPredicate:f];
            Quote *qq = [quoteFiltered objectAtIndex:0];
            [tempArray addObject:qq];
            [qq release];

        } 

        NSLog(@"Count of tempArray == %i", tempArray.count);

        //Set the title;
        rvController.CurrentTitle = cat.title;

        //Push the new table view on the stack
        [self.navigationController pushViewController:rvController animated:YES];

        NSLog(@"QuoteMaps were loaded into tempArray in didSelectRowAtIndexPath method....... ");

        rvController.tableDataSource = tempArray;

        //Increment the Current View
        CurrentLevel = CurrentLevel + 1;
        NSLog(@"             CurrentLevel = %i", CurrentLevel);
        [rvController release];


    } else if(CurrentLevel==0){

        //Get the dictionary of the selected data source.
        Category *cat = [self.tableDataSource objectAtIndex:indexPath.row];

        //Get the children of the present item.
        NSLog(@"category selected was: %@", cat.title);

        NSLog(@"Count of subjects = %i", subjects.count);

        NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"category_title contains[cd] %@", cat.title];

        NSArray *subs = [subjects filteredArrayUsingPredicate:bPredicate];
        NSLog(@"Count of subs = %i", subs.count);


        //Set the title;
        rvController.CurrentTitle = @"Subjects";

        //Push the new table view on the stack
        [self.navigationController pushViewController:rvController animated:YES];

        rvController.tableDataSource = subs;

        //Increment the Current View
        CurrentLevel = CurrentLevel + 1;
        NSLog(@"             CurrentLevel = %i", CurrentLevel);
        [rvController release];


    } else {
        //IF ITS THE DETAIL LEVEL YET

        DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];
        [self.navigationController pushViewController:dvController animated:YES];
        [dvController release];
    }

}

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

@end

Very new to Objective-C and Xcode and working my way through modifying the DrillDownApp tutorial to fit a simple project I have where I drill down through a Category table to a Subject table to a Quote table and then finally a Quote Detail view.

I use the "CurrentLevel" variable to determine which of the above levels I am on however after going through one time through the class, the CurrentLevel seems to get reset to zero. This is after the didSelectRowAtIndexPath method.

I am sure its something super simple and just need a bit of help finding it. I posted the entire class below:

//
//  RootViewController.m
//  DrillDownApp
//
//  Created by iPhone SDK Articles on 3/8/09.
//  Copyright www.iPhoneSDKArticles.com 2009. 
//

#import "RootViewController.h"
#import "DrillDownAppAppDelegate.h"
#import "DetailViewController.h"
#import "Subject.h"
#import "Quote.h"
#import "QuoteMap.h"

@implementation RootViewController

@synthesize tableDataSource, CurrentTitle, CurrentLevel;
@synthesize subjects;
@synthesize quotes;
@synthesize quoteMap;
@synthesize categories;
@synthesize subject_id;
@synthesize subject;
@synthesize category;



- (void)viewDidLoad {
    [super viewDidLoad];
    // Uncomment the following line to add the Edit button to the navigation bar.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

    if(CurrentLevel == 0) {

        //Initialize our table data source
        NSMutableArray *tempArray = [[NSMutableArray alloc] init];
        self.tableDataSource = tempArray;
        [tempArray release];

        // create array that will store the data

        DrillDownAppAppDelegate *appDelegate = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
        self.tableDataSource = [appDelegate categories];
        self.subjects = [appDelegate subjects];
        self.quotes = [appDelegate quotes];
        self.quoteMap = [appDelegate quoteMap];

        NSLog(@"  TableDataSource Count:  %i", self.tableDataSource.count);

        self.navigationItem.title = @"Category";
    }
    else if (CurrentLevel==1) {
        self.navigationItem.title = @"Subject";
        self.title = @"Subject";
    }else if (CurrentLevel==2){
        self.navigationItem.title = @"Quote";
        self.title = @"Quote";
    }else{
        self.navigationItem.title = @"Detail";
        self.title = @"Detail";
    }

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }


    if(CurrentLevel==0){
        NSLog(@"//////   CURRENT LEVEL = 0      LOADING CATEGORIES INTO TABLE...");
        if(self.tableDataSource.count>0){
            Category *cat = [self.tableDataSource objectAtIndex:indexPath.row];
            NSLog(@"         category title = %@", cat.title);
           cell.textLabel.text = cat.title;
        } else {
            NSLog(@"      ERROR: self.tableDataSource has no objects in it!!!!");
        }
    } 
    else if(CurrentLevel==1){
        NSLog(@"//////   CURRENT LEVEL = 1      LOADING SUBJECTS INTO TABLE...");
        if(self.tableDataSource.count>0){
            Subject *sub = [self.tableDataSource objectAtIndex:indexPath.row];
            NSLog(@"         subject title = %@", sub.title);
            cell.textLabel.text = sub.title;
        }
    }
    else if(CurrentLevel==2){
        NSLog(@"//////   CURRENT LEVEL = 2      LOADING QUOTES INTO TABLE...");
        if(self.tableDataSource.count>0){
            Quote *q = [self.quotes objectAtIndex:indexPath.row];
            NSLog(@"         Quote title = %@", q.title);
            cell.textLabel.text = q.title;
        }
    }

    return cell;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    if(CurrentLevel==0){

        DrillDownAppAppDelegate *appDelegate = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
        NSUInteger count = [appDelegate.categories count];
        NSLog(@"Count of records in categories array: %i", count);

        return appDelegate.categories.count;

    }else if(CurrentLevel==1){

        NSUInteger count = [self.tableDataSource count];
        NSLog(@"Count of records in categories array: %i", count);

        return self.tableDataSource.count;    

    }else if(CurrentLevel==2){

        NSUInteger count = [self.quotes count];
        NSLog(@"Count of records in quotes array: %i", count);

        return self.quotes.count;    

    }else{

        return 1;

    }

}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}

#pragma mark Table view methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    //Prepare to tableview.
    RootViewController *rvController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle]];

    NSLog(@"self.CurrentLevel=   %i", self.CurrentLevel);


    if (CurrentLevel==2){


        //Set the title;
        rvController.CurrentTitle = @"Quote";

        //Push the new table view on the stack
        [self.navigationController pushViewController:rvController animated:YES];

        //      rvController.tableDataSource = tempArray;

        //Increment the Current View
        CurrentLevel = CurrentLevel + 1;
        NSLog(@"             CurrentLevel = %i", CurrentLevel);
        [rvController release];


    } else if (CurrentLevel==1) {

        DrillDownAppAppDelegate *appDelegate = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
        self.quotes = [appDelegate quotes];
        self.quoteMap = [appDelegate quoteMap];

        //Get the selected data source.
        Subject *cat = [self.tableDataSource objectAtIndex:indexPath.row];

        //Get the children of the present item.
        NSLog(@"subject_id selected was: %@", cat.subject_id);

        //get the quote_ids from quote_map for this subject_id
        NSPredicate *filterSubjectId = [NSPredicate predicateWithFormat:@"subject_id == %@", cat.subject_id];
        NSArray *quoteMapSection = [self.quoteMap filteredArrayUsingPredicate:filterSubjectId];
        NSLog(@"Count of quoteMapSections = %i", quoteMapSection.count);

        //loop through quote array and create a new array with matching quote_ids
        // TAKE THE QUOTE_ID AND USE INDEXOFOBJECT METHOD TO GRAB QUOTE OBJECT, THEN ADD IT TO THE NEW ARRAY

        QuoteMap *q = [quoteMapSection objectAtIndex:0];
        NSLog(@"   FIRST QUOTEMAP:  %@", q.quote_id);

        NSMutableArray *tempArray = [[NSMutableArray alloc] init];

        for (QuoteMap *qm in quoteMapSection){

            NSLog(@"quote_id=%@",qm.quote_id );
            //use predicate to filter out just the one I want
            NSPredicate *f = [NSPredicate predicateWithFormat:@"quote_id == %@", qm.quote_id];
            NSArray *quoteFiltered = [self.quotes filteredArrayUsingPredicate:f];
            Quote *qq = [quoteFiltered objectAtIndex:0];
            [tempArray addObject:qq];
            [qq release];

        } 

        NSLog(@"Count of tempArray == %i", tempArray.count);

        //Set the title;
        rvController.CurrentTitle = cat.title;

        //Push the new table view on the stack
        [self.navigationController pushViewController:rvController animated:YES];

        NSLog(@"QuoteMaps were loaded into tempArray in didSelectRowAtIndexPath method....... ");

        rvController.tableDataSource = tempArray;

        //Increment the Current View
        CurrentLevel = CurrentLevel + 1;
        NSLog(@"             CurrentLevel = %i", CurrentLevel);
        [rvController release];


    } else if(CurrentLevel==0){

        //Get the dictionary of the selected data source.
        Category *cat = [self.tableDataSource objectAtIndex:indexPath.row];

        //Get the children of the present item.
        NSLog(@"category selected was: %@", cat.title);

        NSLog(@"Count of subjects = %i", subjects.count);

        NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"category_title contains[cd] %@", cat.title];

        NSArray *subs = [subjects filteredArrayUsingPredicate:bPredicate];
        NSLog(@"Count of subs = %i", subs.count);


        //Set the title;
        rvController.CurrentTitle = @"Subjects";

        //Push the new table view on the stack
        [self.navigationController pushViewController:rvController animated:YES];

        rvController.tableDataSource = subs;

        //Increment the Current View
        CurrentLevel = CurrentLevel + 1;
        NSLog(@"             CurrentLevel = %i", CurrentLevel);
        [rvController release];


    } else {
        //IF ITS THE DETAIL LEVEL YET

        DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];
        [self.navigationController pushViewController:dvController animated:YES];
        [dvController release];
    }

}

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

@end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

纵情客 2025-01-04 04:27:05

如果您要更改新创建的 viewController 的 currentLevel,您的代码将有意义。
您可能不想更改当前 viewController 的 currentLevel 变量。

例如,您的代码应该是这样的:

} else if (currentLevel==0) {
    /* more code */
   rvController.currentLevel = self.currentLevel + 1;
   //Push the new table view on the stack
   [self.navigationController pushViewController:rvController animated:YES];
}

在推送 viewController 之前分配新的 currentLevel 非常重要。
您在 viewDidLoad 中检查 currentLevel。当您将 viewController 推入导航堆栈时,会调用此方法。
出于同样的原因,您应该在推送 viewController 之前分配 tableView 的数据源。通常将控制器推送到导航堆栈上是最后要做的事情。


由于 currentLevel 不是类名,因此它应该以小写字母开头。
在 Objective-C 中,只有类(NSString、UIImage、AppDelegate 等)应该以大写字母开头。


但这段代码还有更多问题。据我所知,推送逻辑完全被破坏了。您分配由于 currentLevel 不匹配而未使用的变量。

我建议从一个不重用相同 viewController 的应用程序开始。
为每个级别创建一个 viewController 类。这会让事情变得清楚。一旦你完全理解了这一点,你就应该尝试重用部分。

your code would make sense if you would change the currentLevel of the newly created viewController.
You probably don't want to change the currentLevel variable of your current viewController.

so for example your code should be something like this:

} else if (currentLevel==0) {
    /* more code */
   rvController.currentLevel = self.currentLevel + 1;
   //Push the new table view on the stack
   [self.navigationController pushViewController:rvController animated:YES];
}

it's important to assign the new currentLevel before you push the viewController.
You check for currentLevel in viewDidLoad. This method is called when you push the viewController onto the navigation stack.
Because of the same reason you should assign the dataSource of the tableView before pushing the viewController. Usually pushing the controller on the navigation stack is the last thing to do.


And since currentLevel is not a class name it should start with a lowercase letter.
In Objective-C only classes (NSString, UIImage, AppDelegate etc) should start with an uppercase letter.


But there are more problems in this code. As far as I can see the push logic is completely broken. You assign variables that aren't used because of currentLevel missmatches.

I would suggest to start with an app that doesn't reuse the same viewController.
Create a viewController class for each level. This will clear things up. And once you understand that thing completely you should try the reuse part.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文