Ios 在Objective-C中使用全局变量
首先,我尝试了stackoverflow中给出的几乎所有解决方案,但没有成功实现全局VAR,我甚至做了一个分步教程,但仍然会遇到相同的错误 问题是: 我有一个有几个视图的程序,我想在所有视图上使用变量, 所以我使用了全局变量 我有: GlobalVars.hIos 在Objective-C中使用全局变量,ios,objective-c,unrecognized-selector,Ios,Objective C,Unrecognized Selector,首先,我尝试了stackoverflow中给出的几乎所有解决方案,但没有成功实现全局VAR,我甚至做了一个分步教程,但仍然会遇到相同的错误 问题是: 我有一个有几个视图的程序,我想在所有视图上使用变量, 所以我使用了全局变量 我有: GlobalVars.h #import <UIKit/UIKit.h> extern NSArray *truckBoxes; extern NSArray *farmerlist; extern NSString *farmerCardNumber;
#import <UIKit/UIKit.h>
extern NSArray *truckBoxes;
extern NSArray *farmerlist;
extern NSString *farmerCardNumber;
extern NSString *fName;
@interface GlobalVars : NSObject
{
}
@end
#import <Foundation/Foundation.h>
@class GlobalResource;
extern GlobalResource * R;
@interface GlobalResource : NSObject
{
NSString *myVar;
}
+ (void) loadGlobalResources;
@property (strong, nonatomic, readwrite) NSString *myVar;
@end
我将文件包括在类中(连接到视图控制器):
在.h文件下,我添加了#import“GlobalVars.h
我可以在整个应用程序中访问farmerlist
和truckBoxes
,但无法访问fName
或farmerCardNumber
我可以写入farmerCardNumber
并从同一个视图读取,但如果稍后尝试从另一个视图访问它,我会得到
2013-10-26 11:11:45.612 C3Cms[10427:70b] Branch : 11558
2013-10-26 11:11:59.459 C3Cms[10427:70b] -[__NSArrayM length]: unrecognized selector sent to instance 0x8b7fbc0
2013-10-26 11:11:59.463 C3Cms[10427:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM length]: unrecognized selector sent to instance 0x8b7fbc0'
*** First throw call stack:
(
0 CoreFoundation 0x02a3b5e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x014d58b6 objc_exception_throw + 44
2 CoreFoundation 0x02ad8903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x02a2b90b ___forwarding___ + 1019
4 CoreFoundation 0x02a2b4ee _CF_forwarding_prep_0 + 14
5 Foundation 0x00f0db2d -[NSConcreteMutableAttributedString replaceCharactersInRange:withString:] + 39
6 Foundation 0x00f0e79a -[NSConcreteMutableAttributedString initWithString:attributes:] + 293
7 UIKit 0x001e8116 -[UILabel _setText:] + 97
8 UIKit 0x001e82d4 -[UILabel setText:] + 40
9 C3Cms 0x00001c1d -[printForm viewDidLoad] + 77
10 UIKit 0x0014e9a8 -[UIViewController loadViewIfRequired] + 696
11 UIKit 0x0014ec44 -[UIViewController view] + 35
12 UIKit 0x00168a72 -[UINavigationController _startCustomTransition:] + 778
13 UIKit 0x00175757 -[UINavigationController _startDeferredTransitionIfNeeded:] + 688
14 UIKit 0x00176349 -[UINavigationController __viewWillLayoutSubviews] + 57
15 UIKit 0x002af39d -[UILayoutContainerView layoutSubviews] + 213
16 UIKit 0x000a5dd7 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
17 libobjc.A.dylib 0x014e781f -[NSObject performSelector:withObject:] + 70
18 QuartzCore 0x030d772a -[CALayer layoutSublayers] + 148
19 QuartzCore 0x030cb514 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
20 QuartzCore 0x030cb380 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
21 QuartzCore 0x03033156 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
22 QuartzCore 0x030344e1 _ZN2CA11Transaction6commitEv + 393
23 QuartzCore 0x03034bb4 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
24 CoreFoundation 0x02a0353e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
25 CoreFoundation 0x02a0348f __CFRunLoopDoObservers + 399
26 CoreFoundation 0x029e13b4 __CFRunLoopRun + 1076
27 CoreFoundation 0x029e0b33 CFRunLoopRunSpecific + 467
28 CoreFoundation 0x029e094b CFRunLoopRunInMode + 123
29 GraphicsServices 0x029979d7 GSEventRunModal + 192
30 GraphicsServices 0x029977fe GSEventRun + 104
31 UIKit 0x0003b94b UIApplicationMain + 1225
32 C3Cms 0x00002882 main + 130
33 libdyld.dylib 0x019bc70d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
拆下线路
#import "GlobalVars.h"
在GlobalVars.m.中,不能将外部变量放入*.h文件 所以在GlobalVariables.m中,您有:
extern NSArray *farmerlist;
NSArray *farmerlist;
以及:
不需要
[编辑]
例如:
GlobalVars *globals = [GlobalVars sharedInstance];
globals.fName = @"HelloWorld.txt";
[globals.farmerList addObject:@"Old Macdonald"];
[self processList:[globals farmerList]];
其他
#import "GlobalVars1.h"
GlobalVars1.h
extern NSArray *truckBoxes;
extern NSArray *farmerlist;
extern NSString *farmerCardNumber;
extern NSString *fName;
全球航空公司
#import <UIKit/UIKit.h>
@interface GlobalVars : NSObject
{
}
@end
错误与全局变量无关。错误消息
-[__NSArrayM length]: unrecognized selector sent to instance 0x8b7fbc0
表示您在代码中的某个位置将NSMutableArray
分配给farmerCardNumber
而不是NSString
例如,如果你做了以下事情
farmerCardNumber = [someDictionary objectForKey:@"someKey"];
而[someDictionary objectForKey:@“someKey”]
恰好是一个数组而不是字符串,
然后farmerCardNumber
指向该数组,即使它被声明为指向的指针
一个字符串。你为什么不试试这样的东西呢:
#import "GlobalVars.h"
NSArray *farmerlist;
NSArray *truckBoxes;
NSString *farmerCardNumber = nil;
NSString *fName = nil;
@implementation GlobalVars
{
}
@end
或
似乎您已将可变数组传递给字符串varibale,这就是为什么会出现此错误。实现全局变量并管理其生存期的一种方法(即初始化它们)即使提供全局方法,也要实现一个公开这些变量/方法的类,并使用singleton模式: GlobalVars.h:
#import <Foundation/Foundation.h>
@interface GlobalVars : NSObject
{
NSMutableArray *_truckBoxes;
NSMutableArray *_farmerlist;
NSString *_farmerCardNumber;
NSString *_fName;
}
+ (GlobalVars *)sharedInstance;
@property(strong, nonatomic, readwrite) NSMutableArray *truckBoxes;
@property(strong, nonatomic, readwrite) NSMutableArray *farmerList;
@property(strong, nonatomic, readwrite) NSString *farmerCardNumber;
@property(strong, nonatomic, readwrite) NSString *fName;
@end
然后可以像这样使用这些全局变量,例如:
GlobalVars *globals = [GlobalVars sharedInstance];
globals.fName = @"HelloWorld.txt";
[globals.farmerList addObject:@"Old Macdonald"];
[self processList:[globals farmerList]];
但是,请考虑:
- 您不需要像这样使用全局变量;您应该能够创建一个模型对象,该对象根据需要创建,并将其引用传递给视图。这就是MVC
- 您还发布了一个与Objective-C极为常见的无关问题的堆栈跟踪;只有在您意识到它是什么后,才能修复此错误
#import <UIKit/UIKit.h>
extern NSArray *truckBoxes;
extern NSArray *farmerlist;
extern NSString *farmerCardNumber;
extern NSString *fName;
@interface GlobalVars : NSObject
{
}
@end
#import <Foundation/Foundation.h>
@class GlobalResource;
extern GlobalResource * R;
@interface GlobalResource : NSObject
{
NSString *myVar;
}
+ (void) loadGlobalResources;
@property (strong, nonatomic, readwrite) NSString *myVar;
@end
如何使用
#import "GlobalResource.h"
//then access value as bellow
[GlobalResource loadGlobalResource];
NSLog(@"%@",R.myVar); //value will print here
我应该把NSArray和extern放在哪里?(我的意思是,放在m文件中…)对不起,这是完全错误的。
extern
声明必须放在.h文件中,以便包括此文件在内的其他编译单元知道它。删除行with(Philip的帖子)从m开始写h,并在其他*.m'中用h写extern或此行s@izzy,您必须写入两个文件*.m才能理解extern@skippy:问题中发布的GlobalVars.h和GlobalVars.m是正确的,并且没有问题(据我所知)。如果我这样做,我会收到很多错误,包括“未指定基类而定义的类“globalvars”“实现文件应始终导入自己的接口。我认为这没有问题,也不明白不导入它如何解决上述问题。您的问题是GlobalVars.m既定义了全局变量,又将它们声明为外部变量。您的GlobalVars.h文件无法按原样包括在内。您可能会遇到其他问题,因为GlobalVars.m需要GlobalVars.h中的其他声明,但这是另一回事。如果一个变量同时声明为外部变量并在同一个编译单元中定义,则没有问题,据我所知,这是常见的做法。请看中的第一个示例。在使用之前必须初始化数组them@iOSDeveloper:未初始化的数组为nil,不会导致“无法识别的选择器”异常。不能复制该数组的可能副本,我刚刚在我的整个代码中搜索了farmerCardNumber,它只出现在:farmerCardNumber=txtFarmerCardNumber.text;if([firstBranchName IsequalString:farmerCardNumber])和printFarmerCardNumber.text=farmerCardNumber;在另一个视图中插入NSLog(@“class=%@,[farmerCardNumber class])代码>在您读取变量并检查输出之前不久…我刚刚添加了一个名为testVar的新变量,我得到了相同的错误。您的观察是正确的,它说“2013-10-26 11:46:32.764 C3Cms[10593:70b]class=\uu NSDictionaryM”,但是什么会改变它呢?我用一个新的var做了同样的事情,这个var在整个代码中只声明了2次,并且它说了同样的事情。什么会覆盖它?@izzy:真奇怪。如何分配给testVar
?写完之后,这个类是正确的吗?谢谢你的评论,我得到了Framework/Framework.h,真是太棒了!它起作用了!谢谢对于将来的参考-请更改@property(强、非原子、读写)NSArray*farmerCardNumber;至@property(强、非原子、读写)NSString*farmerCardNumber;接下来的问题是,如果我想要int或double怎么办?如果我使用@property(强、非原子、读写)double*farmerWeight;它表示具有strong的属性必须是类型的对象。否,请使用赋值
而不是strong
,并放下指针(double
而不是double*
)。谢谢!你应该有更多的选票来支持这个。。。!!
#import <Foundation/Foundation.h>
@class GlobalResource;
extern GlobalResource * R;
@interface GlobalResource : NSObject
{
NSString *myVar;
}
+ (void) loadGlobalResources;
@property (strong, nonatomic, readwrite) NSString *myVar;
@end
#import "GlobalResource.h"
GlobalResource *R;
@implementation GlobalResource
@synthesize myVar;
- (void) loadGlobalResources
{
R = [[GlobalResource alloc] init];
}
- (id)init
{
self = [super init];
if (self) {
myVar = @"My Value";
}
return self;
}
@end
#import "GlobalResource.h"
//then access value as bellow
[GlobalResource loadGlobalResource];
NSLog(@"%@",R.myVar); //value will print here