ios 在 Objective-C 中使用全局变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19604523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using global variables in Objective-C
提问by izzy
First of all, I tried almost all the solutions given in stackoverflow but I didn't succeed in implement global vars, I even did a step by step tutorial and still I get the same errors.
首先,我尝试了几乎所有在 stackoverflow 中给出的解决方案,但我没有成功实现全局变量,我什至做了一个分步教程,但仍然出现相同的错误。
heres the issue:
继承人的问题:
I have a program with severals views, I'd like to use variables on all of the views, so I used global variables,
我有一个带有多个视图的程序,我想在所有视图上使用变量,所以我使用了全局变量,
I have:
我有:
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
I include the file in the class (that is connected to the view controller):
under the .h file I add #import "GlobalVars.h
我将文件包含在类中(即连接到视图控制器):在我添加的 .h 文件下 #import "GlobalVars.h
I can access farmerlist
and truckBoxes
from all over the app, but cant access fName
or farmerCardNumber
.
我可以从整个应用程序访问farmerlist
和truckBoxes
,但无法访问fName
或farmerCardNumber
。
I can write to farmerCardNumber
and read from the same view, but if I try to access it later on from another view I get
我可以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
回答by trojanfoe
One way to implement global variables, and to manage their lifetime (i.e. that they are initialized) and even to provide global methods is to implement a class exposing those variables/methods and to use the singleton pattern:
实现全局变量并管理它们的生命周期(即它们被初始化)甚至提供全局方法的一种方法是实现一个暴露这些变量/方法的类并使用单例模式:
GlobalVars.h:
全局变量.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:
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
You can then use these global variables like this, for example:
然后,您可以像这样使用这些全局变量,例如:
GlobalVars *globals = [GlobalVars sharedInstance];
globals.fName = @"HelloWorld.txt";
[globals.farmerList addObject:@"Old Macdonald"];
[self processList:[globals farmerList]];
However, please consider:
但是,请考虑:
- You don't need to use global variables like this; you should be able to create a model object which is created as necessary and reference to it passed to the views. This is MVC.
- You also posted a stack trace of an unrelated issue which is extremely common with Objective-C; only you can fix this error, once you realize what it is.
- 你不需要像这样使用全局变量;您应该能够创建一个根据需要创建的模型对象,并将对它的引用传递给视图。这就是MVC。
- 您还发布了一个无关问题的堆栈跟踪,该问题在 Objective-C 中极为常见;一旦你意识到它是什么,只有你可以修复这个错误。
回答by Martin R
The error has nothing to do with global variables. The error message
该错误与全局变量无关。错误信息
-[__NSArrayM length]: unrecognized selector sent to instance 0x8b7fbc0
indicates that you somewhere in your code assigned a NSMutableArray
to farmerCardNumber
instead of a NSString
.
表示您在代码中的某处分配了NSMutableArray
tofarmerCardNumber
而不是NSString
。
For example, if you do something like
例如,如果你做类似的事情
farmerCardNumber = [someDictionary objectForKey:@"someKey"];
and [someDictionary objectForKey:@"someKey"]
happens to be an arrayand not a string,
then farmerCardNumber
points to that array, even if it was declared as pointer to
a string.
并且[someDictionary objectForKey:@"someKey"]
恰好是一个数组而不是字符串,然后farmerCardNumber
指向该数组,即使它被声明为指向字符串的指针。
回答by MaxEcho
I am using in all my project and working fine.
我在我所有的项目中使用并且工作正常。
GlobalResource.h
全球资源.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
How to use
如何使用
#import "GlobalResource.h"
//then access value as bellow
[GlobalResource loadGlobalResource];
NSLog(@"%@",R.myVar); //value will print here
回答by Kumar Aditya
Why donot you try something like:
你为什么不尝试这样的事情:
#import "GlobalVars.h"
NSArray *farmerlist;
NSArray *truckBoxes;
NSString *farmerCardNumber = nil;
NSString *fName = nil;
@implementation GlobalVars
{
}
@end
or
或者
#import "GlobalVars.h"
NSArray *farmerlist;
NSArray *truckBoxes;
NSString *farmerCardNumber = @"";
NSString *fName = @"";
@implementation GlobalVars
{
}
@end
AND it seems like you have passed mutable array to your string varibale, that is why you are getting that error.
并且似乎您已将可变数组传递给字符串变量,这就是您收到该错误的原因。
回答by Philip Sheard
Remove the line
删除该行
#import "GlobalVars.h"
from GlobalVars.m.
来自 GlobalVars.m。
回答by theWalker
You can't put extern variables to *.h file.
您不能将外部变量放入 *.h 文件。
So in GlobalVariables.m you have:
所以在 GlobalVariables.m 你有:
extern NSArray *farmerlist;
NSArray *farmerlist;
And:
和:
@interface GlobalVars : NSObject
{
}
@end
@implementation GlobalVars
{
}
@end
are not needed
不需要
[edit]
[编辑]
for example:
例如:
Other.m
其他.m
#import "GlobalVars1.h"
GlobalVars1.h
全局变量1.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