我的AppDelegate.m
中有一个名为message
的变量,我想在视图控制器中使用它,但它不起作用。我试过这个解决方案:
AppDelegate.m
导入我的ViewController.m
,我会收到错误:clang: error: linker command failed with exit code 1 (use -v to see invocation)
,但如果我不导入它,我会收到:No known class method for selector 'message'
此处line:self.toSort = [AppDelegate message];
。但是当我将ViewController.m
导入AppDelegate.m
时,我没有收到链接器命令错误,但是其他错误已经存在。 我的AppDelegate.h
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, strong) PNChannel *myChannel;
- (void)getMessage;
AppDelegate.m
#import "AppDelegate.h"
#import "ViewController.m"
static NSArray *_message = nil;
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// [self.window makeKeyAndVisible];
self.myChannel = [PNChannel channelWithName:currentChannel.username
shouldObservePresence:YES];
[self getMessage];
}
+ (NSArray *)message
{
if (_message)
return _message;
AppDelegate *appDelegate =(AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate getMessage];
return nil;
}
- (void)getMessage {
[PubNub requestFullHistoryForChannel:self.myChannel withCompletionBlock:^(NSArray *contentArray, PNChannel *channel, PNDate *fromDate, PNDate *toDate, PNError *error) {
_message = contentArray;
NSLog(@"test log %@", _message);
}];
}
ViewController.m
#import "ViewController.h"
//#import "AppDelegate.h"
//#import "AppDelegate.m"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
//AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
//[appDelegate getMessage];
self.toSort = [AppDelegate message];
[self getMessageList];
}
我确定我做了一些初学者的错误,但我无法理解。 “测试日志”有效,所以我认为我必须以不同的方式调用它。
已经尝试过这个,但也会收到错误,因为邮件不是属性。
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *variableTest = appDelegate.message;
NSLog(@"TEST : %@",variableTest);
更新:我试过这个,但测试日志显示为null,所以有些事情仍然是错误的。
AppDelegate.h
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, strong) PNChannel *myChannel;
@property (strong, nonatomic) NSArray *message;
- (void)getMessage;
AppDelegate.m
#import "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// [self.window makeKeyAndVisible];
self.myChannel = [PNChannel channelWithName:currentChannel.username
shouldObservePresence:YES];
[self getMessage];
}
return YES;
}
+ (NSArray *)message
{
if (self.message)
return self.message;
AppDelegate *appDelegate =(AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate getMessage];
return nil;
}
- (void)getMessage {
[PubNub requestFullHistoryForChannel:self.myChannel withCompletionBlock:^(NSArray *contentArray, PNChannel *channel, PNDate *fromDate, PNDate *toDate, PNError *error) {
self.message = contentArray;
NSLog(@"dev log %@", self.message);
}];
}
ViewController.m
- (void)viewWillAppear:(BOOL)animated {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *variableTest = appDelegate.message;
NSLog(@"TEST : %@",variableTest);
}
我的尝试基于o Pi的回答:
@interface MessageHistoryData : NSObject {
NSArray *yourData;
}
@property(nonatomic,retain) NSArray *yourData;
+(MessageHistoryData *)getInstance;
@end
#import "MessageHistoryData.h"
@implementation MessageHistoryData @synthesize yourData;
static MessageHistoryData *instance =nil;
+(MessageHistoryData *)getInstance {
@synchronized(self) {
if(instance==nil) {
instance= [MessageHistoryData new];
}
}
return instance;
}
@end
在我的ViewController.m中(MessageHistoryData导入.h)
- (void)setupArray {
[PubNub requestHistoryForChannel:my_channel from:nil to:nil limit:100 reverseHistory:NO withCompletionBlock:^(NSArray *contentArray, PNChannel *channel, PNDate *fromDate, PNDate *toDate, PNError *error) {
MessageHistoryData *data = [MessageHistoryData getInstance];
data.yourData = contentArray;
NSLog(@"Dev log2 %@", data.yourData);
}];
}
答案 0 :(得分:4)
我设置了一个示例项目来验证这是否有效。
在AppDelegate.h文件中,公开声明message
属性和-getMessage
方法:
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (readonly, nonatomic) NSString *message;
- (void)getMessage;
@end
在AppDelegate.m文件中,像往常一样实现你的方法(我为了举例明确地设置了属性):
#import "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
}
- (void)getMessage {
self.message = @"This is a message";
}
@end
在ViewController.m
文件中,您应该导入AppDelegate标头,您应该可以自由访问这些属性:
#import "AppDelegate.h"
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSLog(@"The delegate's message is: %@", delegate.message); // Logs "The delegate's message is: (null)"
[delegate getMessage];
NSLog(@"The delegate's message is: %@", delegate.message); // Logs "The delegate's message is: This is a message"
}
@end
如果上述方法无效,您应该测试PubNub
课程并确保其行为可预测。
我不建议永久存储AppDelegate中的信息,因为这使得该课程不仅仅是作为您的应用程序的系统委托。这样的信息应存储在专用存储中,或通过自定义PubNub
子类提供,该子类作为单例访问(如果没有要管理的全局状态!)或逐个实例
如果您需要任何澄清或上述解决方案对您不起作用,请告诉我。
编辑:单身人士建议
根据我的评论,这是处理跨视图控制器共享网络数据的一种方法
@interface NetworkClient : PubNub
@property (readonly, nonatomic) NSString *message;
/**
* Returns a shared network client to be used throughout the app
*/
+ (instancetype)sharedClient;
- (void)configureWithChannel:(PNChannel*)channel;
- (void)clearChannel;
- (void)getMessagesWithCompletionHandler:(void (^)(NSArray *, PNChannel *, PNDate *, PNDate *, PNError *))
@end
其中sharedInstance使用technique described here来设置您的实例。从那里,您可以使用[NetworkClient sharedClient]
访问客户端,并通过客户端上的实例方法或属性检索任何数据。
我也猜测你是新手单身人士或iOS的新手,所以我建议你阅读this article关于使用单身人士的信息,以及博客objc.io来熟悉自己有一些绝对会让你的生活更轻松的最佳实践。
答案 1 :(得分:2)
首先,不需要声明变量static,因为[UIApplication sharedAppliction] delegate]
将始终是同一个实例。所以只需在AppDelegate.h
文件中声明一个属性并使用它。
@property(nonatomic, strong) NSArray *message;
AppDelegate.m中的使用它:
self.message
在您的视图控制器中导入.h并执行:
AppDelegate *appDelegate =(AppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *arr = appDelegate.message;
答案 2 :(得分:1)
您必须将公共变量放入头文件中。
答案 3 :(得分:1)
您的getMessage
方法使用异步调用来获取消息。如果您无法以同步方式检索它,则可以尽快致电getMessage
。
更好的是,您还可以使用块来返回消息异步:
+ (void)asyncMessage:(void(^)(NSArray * message))callbackBlock
{
if (_message)
{
callbackBlock(_message);
return;
}
[PubNub requestFullHistoryForChannel:self.myChannel withCompletionBlock:^(NSArray *contentArray, PNChannel *channel, PNDate *fromDate, PNDate *toDate, PNError *error) {
_message = contentArray;
callbackBlock(_message);
NSLog(@"test log %@", _message);
}];
}
答案 4 :(得分:1)
永远不会在xcode中导入.m类,因为这会抛出cling:error。
如果你想在NSArray
中定义的appdelegate
稍后在你的任何视图控制器中使用,可能会有很多方法。其中一些是 -
在appdelegate.h
中像这样启动你的数组
@property(nonatmoic,retain)nsarray *message;
然后在appdelegate.m
类的didfinishlaunchingwithOptions
类中为此数组分配内存 -
message=[[nsarray alloc]initwithobjects:@"abc"];
然后在你的视图控制器中创建app委托对象并访问此属性,如下所示 -
NSLog(@"array is %@",appdelegateobject.message);
在你的第一个问题中,你试图通过类方法返回这个数组,但是在appdelegate中你返回nil,那么你将如何得到这个消息数组,
答案 5 :(得分:0)
获取消息变量并将其粘贴到.h中,然后从.m
中删除它答案 6 :(得分:0)
您无法像这样在工具文件中导入工具文件。
AppDelegate.m
#import "AppDelegate.h"
#import "ViewController.m" // This is the reason causes error.
我之前犯过这个错误....
像这样修改很容易解决这个问题。
AppDelegate.m
#import "AppDelegate.h"
#import "ViewController.h"
答案 7 :(得分:-1)
您需要将消息数组的属性设为公开
AppDelegate.h
@property (strong, nonatomic) NSArray *message;
希望它可以帮助你..