在Objective-C中使用全局variables

首先,我尝试了几乎所有在stackoverflow中给出的解决scheme,但我没有成功实现全局variables,我甚至做了一步一步的教程,但我仍然得到相同的错误。

inheritance人的问题:

我有一个多视图的程序,我想在所有的视图上使用variables,所以我使用全局variables,

我有:

GlobalVars.h

#import <UIKit/UIKit.h> extern NSArray *truckBoxes; extern NSArray *farmerlist; extern NSString *farmerCardNumber; extern NSString *fName; @interface GlobalVars : NSObject { } @end 

GlobalVars.m

 #import "GlobalVars.h" NSArray *farmerlist; NSArray *truckBoxes; NSString *farmerCardNumber; NSString *fName; @implementation GlobalVars { } @end 

我将该文件包含在类(连接到视图控制器)中:在.h文件下添加#import "GlobalVars.h

我可以从所有的应用程序访问farmerlisttruckBoxes ,但不能访问fNamefarmerCardNumber

我可以写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 

实现全局variables并pipe理其生命周期(即初始化它们)甚至提供全局方法的一种方法是实现暴露这些variables/方法的类并使用单例模式:

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.m:

 #import "GlobalVars.h" @implementation GlobalVars @synthesize truckBoxes = _truckBoxes; @synthesize farmerList = _farmerList; @synthesize frameCardNumber = _frameCardNumber; @synthesize fName = _fName; + (GlobalVars *)sharedInstance { static dispatch_once_t onceToken; static GlobalVars *instance = nil; dispatch_once(&onceToken, ^{ instance = [[GlobalVars alloc] init]; }); return instance; } - (id)init { self = [super init]; if (self) { _truckBoxes = [[NSMutableArray alloc] init]; _farmerlist = [[NSMutableArray alloc] init]; // Note these aren't allocated as [[NSString alloc] init] doesn't provide a useful object _farmerCardNumber = nil; _fName = nil; } return self; } @end 

然后你可以像这样使用这些全局variables,例如:

 GlobalVars *globals = [GlobalVars sharedInstance]; globals.fName = @"HelloWorld.txt"; [globals.farmerList addObject:@"Old Macdonald"]; [self processList:[globals farmerList]]; 

但请考虑:

  • 你不需要像这样使用全局variables; 你应该能够创build一个模型对象,它是根据需要创build的,并引用它传递给视图。 这是MVC。
  • 您还发布了一个与Objective-C非常相似的无关问题的堆栈跟踪; 一旦你意识到这是什么,只有你可以修复这个错误。

这个错误与全局variables无关。 错误消息

 -[__NSArrayM length]: unrecognized selector sent to instance 0x8b7fbc0 

表示你在你的代码中某个地方分配了一个NSMutableArrayfarmerCardNumber而不是一个NSString

例如,如果你做类似的事情

 farmerCardNumber = [someDictionary objectForKey:@"someKey"]; 

[someDictionary objectForKey:@"someKey"]碰巧是一个数组而不是一个string,然后farmerCardNumber指向该数组,即使它被声明为指向string的指针。

为什么不试试这样的:

 #import "GlobalVars.h" NSArray *farmerlist; NSArray *truckBoxes; NSString *farmerCardNumber = nil; NSString *fName = nil; @implementation GlobalVars { } @end 

要么

 #import "GlobalVars.h" NSArray *farmerlist; NSArray *truckBoxes; NSString *farmerCardNumber = @""; NSString *fName = @""; @implementation GlobalVars { } @end 

而且好像你已经将可变数组传递给你的stringvaribale,这就是为什么你得到这个错误。

我正在使用我的所有项目,工作正常。

GlobalResource.h

 #import <Foundation/Foundation.h> @class GlobalResource; extern GlobalResource * R; @interface GlobalResource : NSObject { NSString *myVar; } + (void) loadGlobalResources; @property (strong, nonatomic, readwrite) NSString *myVar; @end 

GlobalResource.m

 #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 

删除线

 #import "GlobalVars.h" 

来自GlobalVars.m。

你不能把外部variables放到* .h文件中。

所以在GlobalVariables.m中你有:

 extern NSArray *farmerlist; NSArray *farmerlist; 

和:

 @interface GlobalVars : NSObject { } @end @implementation GlobalVars { } @end 

不需要

[编辑]

例如:

Other.m

 #import "GlobalVars1.h" 

GlobalVars1.h

 extern NSArray *truckBoxes; extern NSArray *farmerlist; extern NSString *farmerCardNumber; extern NSString *fName; 

GlobalVars.h

 #import <UIKit/UIKit.h> @interface GlobalVars : NSObject { } @end 

GlobalVars.m

 #import "GlobalVars.h" NSArray *farmerlist; NSArray *truckBoxes; NSString *farmerCardNumber; NSString *fName; @implementation GlobalVars { } @end