【问题标题】:Retrieve data from NSObject's property从 NSObject 的属性中检索数据
【发布时间】:2014-07-02 14:57:25
【问题描述】:

我有一个名为GlobalArray 的类,它是一个NSObject。它有一个名为globalDataNSArray 属性。

我正在将数据传递到我的ViewControllerOne.m 内的globalData,它运行良好,我可以在控制台中打印日志。问题是,我无法在ViewControllerTwo.m 中检索这些数据。

GlobalArray.h

#import <Foundation/Foundation.h>

@interface GlobalArray : NSObject

@property (nonatomic, retain) NSArray *globalData; // why retain?

GlobalArray.m

#import "GlobalArray.h"

@implementation GlobalArray

- (id) init
{
    self = [super init];
    if(self)
    {
        self.globalData = [[NSArray alloc] init];
    }
    return(self);
}

ViewControllerOne.m(GlobalArray.h 导入到 .h)

- (void)viewWillAppear:(BOOL)animated {

  [PubNub requestHistoryForChannel:my_channel from:nil to:nil limit:100 reverseHistory:NO withCompletionBlock:^(NSArray *message, PNChannel *channel, PNDate *fromDate, PNDate *toDate, PNError *error) {

            GlobalArray *fromHistory = [[GlobalArray alloc] init];
            fromHistory.globalData = message;
            NSLog(@"TEST LOG 1 %@", fromHistory.globalData);

}];
}

我尝试以这种方式在 ViewControllerTwo.m 中检索它:(已导入 ViewController.h 和 GlobalArray.h)

-(void) viewWillAppear:(BOOL)animated {

    GlobalArray *history = [[GlobalArray alloc] init];
    NSArray *sampleArr = [[NSArray alloc] init];
    sampleArr = history.globalData;
    NSLog(@" TEST LOG2 %@", sampleArr);


}

但是 TEST LOG2 是空的。我想我错过了 ViewControllerTwo.m 中的某些内容,但无法弄清楚,对我来说这似乎是正确的。

【问题讨论】:

  • 那些GlobalArray 对象是在本地分配的,在这些方法之外是不可见的。您想要一个单例模式,但是,您需要先了解有关变量范围的更多信息。
  • 如果您希望您的GlobalArray 在您的整个应用程序中可用,您必须将其转换为单例。
  • @trojanfoe 我不想要一个单例,在我的情况下这不是一个好的解决方案。我只需要在另外两个视图控制器中访问这个数组。
  • 我在这里说明了为什么要避免单身:stackoverflow.com/questions/24477242/…
  • 将数据也传递给中间控制器,顺便说一句,您的用例(我正在阅读另一篇文章)我认为单例是最优雅的解决方案。文章声明避免滥用单例,而不是全部避免。

标签: ios objective-c nsobject


【解决方案1】:

如果您想避免经典的单例模式,您可以将会话对象绑定到应用委托并实现登录/注销方法:

@interface XXXAppDelegate : UIResponder <UIApplicationDelegate>

+ (XXXSession *)loginWithUserName:(NSString*)userName password:(NSString*)password;
+ (void)logout;

+ (XXXSession)currentSession;

@end

然后您定义会话中管理的数据:

@interface XXXSession : NSObject

@property (nonatomic, retain) NSArray *globalData;

@end

在应用程序中初始化会话对象:didiFinishLaunchingWithOptions:或在您的应用程序中需要它的地方:

@implementation XXXAppDelegate {
    XXXSession *_currentSession;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self loginWithUserName: @"Test"];
}

@end

在您的 ViewControllers 中,您可以按如下方式获取会话:

[XXXAppDelegate currentSession].globalData

这种方法类似于拥有一个单例对象,不同之处在于对实例的访问不是由单例类本身提供(如本设计模式的定义中所述),而是在应用程序委托中实现。

【讨论】:

  • 我在应用程序委托中移动了登录/注销方法,因为它们在那里更合适,而不是在会话对象中
【解决方案2】:

当然,您会得到空的,因为您正在 ViewControllerTwo 中初始化一个 GlobalArray 类型的单独对象。 这就像你做的那样:

Car car1 = [[Car alloc] init];
car1.name = @"BMW";
Car car2 = [[Car alloc] init];
NSLog(@"Car name = %@", car2.name);    <--- this will be empty!

您需要将 GlobalArray 变量保存在某处以便稍后在 ViewControllerTwo 中访问它而不是重新初始化它,或者使 GlobalArray 类单例始终返回相同的实例而不是创建单独的实例。

【讨论】:

  • 举个例子,我应该把它存放在哪里?
  • 例如在应用程序委托中,或在另一个可全局访问的对象内部。这种方法不太好,但如果你坚持不做单例,这是一种方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 2013-07-21
相关资源
最近更新 更多