AppDelegate从不同的类访问,从RootController.m
我的问题是从控制器(这恰好是我的rootViewController)获取信息到另一个视图。在试图通过应用程序委托访问它时,我无法使其工作。我已经找到了如何做到这一点,但是这又引起了另一个让模态视图控制器中的视图实际显示数据的问题。下面我已经发布了appDelegate信息和NSMutable Dictionary解决方案代码,以供那些可能需要帮助的人员使用。AppDelegate从不同的类访问,从RootController.m
我已经尝试了一个多星期来解决我自己的问题。我的问题最终是如何访问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
and in viewController.m file;
#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
我希望这可以帮助别人得到这个直,因为它确实花了我很多时间,我希望你可以从我的教训得到位。
真诚, 柯克
我没有看到你填充在DetailsViewController
的selectedMaker
与伊娃在应用委托的`selectedMaker”数据的任何一点。仅仅因为它们具有相同的名称并不意味着它们共享相同的数据。
您需要将应用程序委托中的值分配或复制到视图控制器。快速和肮脏的方法是做这样的事情:
@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];
}
Edit01:
所以......在TechZen的建议,我 试图将我的NSDictionary我的RootViewController的的 。
(1)我不知道为什么你有SelectedMaker
类应该完成。你似乎已经与NSMutableDictionary
混淆了课程。该类没有任何明显的理由返回包含它自己的iVars值的字典。这完全是多余的。您似乎已经有一个名为ViolinMaker
的类,它封装了每个小提琴制造商记录的所有数据。
(2)SelectedMaker
的初始化方法没有正确实现。看起来你必须在致电-[SelectedMaker init]
之前致电-[SelectedMaker initWithsName:..]
,否则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)您需要每个viewcontroller中的代码来访问应用程序委托中的数组/集合,以便viewcontroller可以选择它需要的ViolinMaker实例。
Edit02:
没有我不能使用那些3线,作为 'objectAtIndex:indexPath.row' 是仅 的didSelectRow 函数内可用。这意味着我将不得不 重建表和它的所有 数据。
您只是在您的应用程序委托中将字典定义为实例变量。所以,你会有一个可变的字典,其中每个值是ViolinMaker
,每个键都是小提琴制造者的某个属性,例如名字。我们称之为violinMakersDict
。然后,在应用程序的任何位置,首先调用应用程序委托并访问violinMakersDict,即可访问字典。
要填充表格,您需要将一些值作为数组提取。最有可能的是,你会拿小提琴制造者的名字。然后,您将按字母顺序对数组进行排序,然后使用index.row值将数组中的值填充到每行中。
同样,如果您需要在一个视图中添加数据,您可以写入violinMakersDict
,然后通过再次调用应用程序委托从另一个视图访问该数据。
非常酷,这正是我所要求的,因为我确实感到我正在实例化一个新变量,并且它只是具有相同的名称......但是,如何将值加载到appDelegate?对不起,我只是不知道如何将这些值加载到Appdelegate中?非常感谢! Kirk – Digiguy 2009-11-24 16:12:08
对不起,我不喜欢这个网站,我非常感谢你的帮助TechZen。 我的问题是,我从RootViewController(UITableViewController,在tableView didSelectRowAtIndexPath内)加载NSMuteableDictionary,而不是在AppDelegate中。我可以在那里加载信息,我只是不知道如何从那里进入另一个视图。我看到你在说什么,但它只是说黄色警告'UIApplication可能不会响应'选定的制造商' – Digiguy 2009-11-24 18:24:37
如果数据在rootViewController中,您需要将数组分配给子控制器,然后再将其推入导航堆栈。 (如果您要求,我可以稍后提供示例。)通常,您不会将数据保存在视图控制器中。应该有单独的对象来保存数据。如果多个控制器必须访问数据,则情况尤其如此。应用程序代表通常是停放它的最佳位置。阅读Model-View-Controller设计模式。了解所有基于Objective-C的API如何工作非常重要。 – TechZen 2009-11-24 20:17:19
这是什么问题?你把它编辑出来了吗? – 2009-12-05 04:10:57