1

我的問題是從控制器(這恰好是我的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 

我希望這可以幫助別人得到這個直,因爲它確實花了我很多時間,我希望你可以從我的教訓得到位。

真誠, 柯克

+0

這是什麼問題?你把它編輯出來了嗎? – 2009-12-05 04:10:57

回答

2

我沒有看到你填充在DetailsViewControllerselectedMaker與伊娃在應用委託的`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,然後通過再次調用應用程序委託從另一個視圖訪問該數據。

+0

非常酷,這正是我所要求的,因爲我確實感到我正在實例化一個新變量,並且它只是具有相同的名稱......但是,如何將值加載到appDelegate?對不起,我只是不知道如何將這些值加載到Appdelegate中?非常感謝! Kirk – Digiguy 2009-11-24 16:12:08

+0

對不起,我不喜歡這個網站,我非常感謝你的幫助TechZen。 我的問題是,我從RootViewController(UITableViewController,在tableView didSelectRowAtIndexPath內)加載NSMuteableDictionary,而不是在AppDelegate中。我可以在那裏加載信息,我只是不知道如何從那裏進入另一個視圖。我看到你在說什麼,但它只是說黃色警告'UIApplication可能不會響應'選定的製造商' – Digiguy 2009-11-24 18:24:37

+0

如果數據在rootViewController中,您需要將數組分配給子控制器,然後再將其推入導航堆棧。 (如果您要求,我可以稍後提供示例。)通常,您不會將數據保存在視圖控制器中。應該有單獨的對象來保存數據。如果多個控制器必須訪問數據,則情況尤其如此。應用程序代表通常是停放它的最佳位置。閱讀Model-View-Controller設計模式。瞭解所有基於Objective-C的API如何工作非常重要。 – TechZen 2009-11-24 20:17:19