1

我的问题是从控制器(恰好是我的 rootViewController)获取信息到另一个视图。在尝试通过应用程序委托访问它时,我无法让它工作。我已经找到了如何做到这一点,但这反过来又产生了另一个问题,即在模态视图控制器中获取视图以实际显示数据。下面我发布了 appDelegate 信息和 NSMutable Dictionary 解决方案代码,供那些可能也需要帮助的人使用。

我已经尝试了一个多星期来自己解决这个问题。我的问题最终是如何访问 appDelegate,这就是我遇到 NSDictionary 问题的原因。所以最终问题不是 NSDictionary,尽管我敢肯定,如果我走得更远,那将是一个问题。

首先,我要感谢 TechZen 帮助我看到我已经过度编程,并为我指明了正确的方向。

这是我学到的。

在 appDelegate 中分配您的变量。

AppDelegate.h

 @interface AppDelegate : NSObject  < UIApplicationDelegate, UINavigationControllerDelegate >
{   
    UIWindow *window;
    UINavigationController *navController;

    // Array to store the Makers Objects
    NSMutableArray *makers;

}

@property (nonatomic, retain) IBOutlet UIWindow *window; 
@property (nonatomic, retain) IBOutlet UINavigationController *navController;

@property (retain, nonatomic) NSMutableArray *makers;
@end

AppDelegate.m

    - (void)applicationDidFinishLaunching:(UIApplication *)application 
{

    makers = [[NSMutableArray alloc] init] ;
}

在 ViewController.m 中将变量分配给 appDelegate。我在 tableView 函数 didSelectRowAtIndexPath 中执行了此操作。

        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

// The line below loads it into the variable, the one above takes it and makes it available for other view Controllers.

       Maker *maker = (Maker *)[appDelegate.makers objectAtIndex:indexPath.row];

// the combination of the above and below also loads the information into another array in this view controller, defined in an NSObject Controller called Maker (.h and .m files)

      maker = [self.Makers objectAtIndex:indexPath.row];

现在在您的视图控制器中,您想从 appDelegate 加载变量,像这样设置它。

#import <UIKit/UIKit.h>

#import "AppDelegate.h"
#import "Maker.h"

@class AppDelegate;

@interface DetailsViewController : UIViewController
{

        AppDelegate *dappDelegate;
    DetailsViewController *detailsView;

    IBOutlet UITextView *makerDescription;

}

@property (retain, nonatomic) AppDelegate *dappDelegate;

@property (nonatomic, retain) DetailsViewController *detailsView; 

@property (nonatomic, retain) IBOutlet UITextView *makerDescription;

@end

在 viewController.m 文件中;

#import "DetailsViewController.h"
#import "AppDelegate.h"

@synthesize dappDelegate;

- (void)viewWillAppear:(BOOL)animated // or ViewDidLoad not sure which is better.

    dappDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
    NSString *newLocalVariable = [dappDelegate.makers description];

NSLog(@"newLocalVariable: %@", [dappDelegate.makers description]);
// This is for verifying you have it loaded. 'description' is defined in the Maker NSObject, see below for those files, and above for where it was assigned originally

.....并将其分配给您现在想要的任何东西!

我希望这对每个人都有帮助。此时您可以将 NSArray 从那里放到 NSDictionary 中,但是现在使用键和值进行访问,因此此时访问有点复杂,但当然有优势。我还不能完全把它弄下来,现在已经放弃了这种方法,只使用一个 NSArray 。

下面是 Makers h 和 m 文件的示例,您也可以查看。

Maker.h

@interface Maker : NSObject 
{
    NSString *name;
    NSString *address;
    NSString *city;
    NSString *postalcode;
    NSString *country;
    NSString *phonenumber;
    NSString *email;
    NSString *description;
    NSString *services;
    NSString *website;
}

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *address;
@property (nonatomic, copy) NSString *city;
@property (nonatomic, copy) NSString *postalcode;
@property (nonatomic, copy) NSString *country;
@property (nonatomic, copy) NSString *phonenumber;
@property (nonatomic, copy) NSString *email;
@property (nonatomic, copy) NSString *description;
@property (nonatomic, copy) NSString *services;
@property (nonatomic, copy) NSString *website;

- (id)initWithName:(NSString *)n address:(NSString *)a city:(NSString *)c postalcode:(NSString *)z country:(NSString *)o phonenumber:(NSString *)p email:(NSString *)e description:(NSString *)d services:(NSString *)s website:(NSString *)w;

@end

及其 Maker.m 文件;

#import "ViolinMaker.h"

@implementation Maker
@synthesize name, address, city, postalcode, country, phonenumber, email, description, services, website;

- (id)initWithName:(NSString *)n address:(NSString *)a city:(NSString *)c postalcode:(NSString *)z country:(NSString *)o phonenumber:(NSString *)p email:(NSString *)e description:(NSString *)d services:(NSString *)s website:(NSString *)w; 
{
    self.name = n;
    self.address = a;
    self.city = c;
    self.postalcode = z;
    self.country = o;
    self.phonenumber = p;
    self.email = e;
    self.description = d;
    self.services = s;
    self.website = w;
    return self;
}
@end

我希望这可以帮助其他人弄清楚这一点,因为这确实花费了我很多时间,我希望你能从我学到的东西中有所收获。

真诚的,柯克

4

1 回答 1

2

我没有看到您使用来自应用程序委托的“selectedMaker”的数据填充selectedMakerivar 的任何点。DetailsViewController仅仅因为它们具有相同的名称并不意味着它们共享相同的数据。

您需要将值从应用程序委托分配或复制到视图控制器。快速而肮脏的方法是执行以下操作:

@implementation DetailsViewController

...

-(void) viewDidLoad{
//selectedMaker=[[UIApplication sharedApplication] selectedMaker]; <-- this is wrong
//Edit, this is the correct call to app delegate
selectedMaker=[[[UIApplication sharedApplication] delegate] selectedMaker]; 
}

编辑01:

所以...在 TechZen 的建议下,我试图将我的 NSDictionary 移出我的 RootViewController。

(1)我不确定为什么你有SelectedMaker它应该完成的课程。您似乎将课程与NSMutableDictionary. 该类没有任何明显的理由返回包含它自己的 iVar 值的字典。这是完全多余的。您似乎已经有一个名为的类ViolinMaker,它封装了每个小提琴制造商记录的所有数据。

(2) 的初始化方法SelectedMaker没有正确实现。看起来你必须在调用-[SelectedMaker initWithsName:..]之前调用,-[SelectedMaker init]否则 init 不知道键是什么。

(3) 无论如何,在didSelectRow方法中,您实际上并没有初始化 SelectedMaker. 这一行:

SelectedMaker *selectedMaker = [[[NSMutableDictionary alloc]retain] initWithObjects: objects forKeys: keys];

不创建一个实例,SelectedMaker而是一个NSMutableDictionary或多或少地将它转换为SelectedMaker类。这就是为什么你从 for 循环中得到编译器警告的原因。

(4) 我认为根本不需要SelectedMaker上课。这些行:

ViolinMakerAppDelegate *appDelegate = (ViolinMakerAppDelegate *)[[UIApplication sharedApplication] delegate];
ViolinMaker *violinMaker = (ViolinMaker *)[appDelegate.violinMakers objectAtIndex:indexPath.row];
violinMaker = [self.filteredViolinMakers objectAtIndex:indexPath.row];

似乎为您提供了填充表格或详细信息视图中任何特定行所需的所有信息。appDelegate.violinMakers'. The您可以在需要访问violinMaker`对象中数据的任何视图中使用这三行,其中包含您需要的所有数据。

我认为你让这变得比它必须的更复杂。您所需要的只是 (A) 一个封装从 SQL 获取的每条记录的数据的类。在这种情况下,看起来 ViolinMaker 会这样做。(B) 您需要在应用程序委托中使用一个数组(或其他集合)来存储多个 ViolinMaker 实例。(C) 您需要每个视图控制器中的代码来访问应用程序委托中的数组/集合,以便视图控制器可以选择它需要的 ViolinMaker 实例。

编辑02:

不,我不能使用这 3 行,因为 'objectAtIndex:indexPath.row' 仅在 didSelectRow 函数中可用。这意味着我必须重建表及其所有数据。

您只需将字典定义一次作为应用程序委托中的实例变量。因此,您将拥有一个可变字典,其中每个值ViolinMaker和每个键都是小提琴制造商的某些属性,例如名称。让我们称之为violinMakersDict.然后,在您的应用程序中的任何位置,您都可以通过首先调用应用程序委托和访问 violinMakersDict 来访问字典。

要填充表格,您需要将一些值提取为数组。最有可能的是,您会使用小提琴制造商名称的钥匙。然后您将按字母顺序对数组进行排序,然后您将使用数组中 index.row 值处的值填充每一行。

同样,如果您需要在一个视图中添加数据,您可以写入,violinMakersDict然后通过再次调用应用委托从另一个视图访问该数据。

于 2009-11-24T14:46:45.130 回答