First of all, I tried almost all the solutions given in * but I didn't succeed in implement global vars, I even did a step by step tutorial and still I get the same errors.
首先,我尝试了几乎所有在*中给出的解决方案,但我没有成功实现全局变量,我甚至做了一步一步的教程,但我仍然得到相同的错误。
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
GlobalVars.h
#import <UIKit/UIKit.h>
extern NSArray *truckBoxes;
extern NSArray *farmerlist;
extern NSString *farmerCardNumber;
extern NSString *fName;
@interface GlobalVars : NSObject
{
}
@end
GlobalVars.m
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
6 个解决方案
#1
32
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:
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:
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.
- 你不需要像这样使用全局变量;您应该能够创建一个模型对象,该对象是根据需要创建的,并引用它传递给视图。这是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.
- 您还发布了一个不相关问题的堆栈跟踪,这在Objective-C中非常常见;一旦你意识到它是什么,只有你能解决这个错误。
#2
4
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分配给farmerCardNumber而不是NSString。
For example, if you do something like
例如,如果你做了类似的事情
farmerCardNumber = [someDictionary objectForKey:@"someKey"];
and [someDictionary objectForKey:@"someKey"]
happens to be an array and not a string, then farmerCardNumber
points to that array, even if it was declared as pointer to a string.
并且[someDictionary objectForKey:@“someKey”]恰好是一个数组而不是一个字符串,那么farmerCardNumber指向该数组,即使它被声明为指向字符串的指针。
#3
0
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.
似乎你已经将可变数组传递给你的字符串varibale,这就是你得到那个错误的原因。
#4
0
I am using in all my project and working fine.
我在我的所有项目中使用并且工作正常。
GlobalResource.h
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
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
#5
-1
Remove the line
删除该行
#import "GlobalVars.h"
from GlobalVars.m.
来自GlobalVars.m。
#6
-1
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
Other.m
#import "GlobalVars1.h"
GlobalVars1.h
GlobalVars1.h
extern NSArray *truckBoxes;
extern NSArray *farmerlist;
extern NSString *farmerCardNumber;
extern NSString *fName;
GlobalVars.h
GlobalVars.h
#import <UIKit/UIKit.h>
@interface GlobalVars : NSObject
{
}
@end
GlobalVars.m
GlobalVars.m
#import "GlobalVars.h"
NSArray *farmerlist;
NSArray *truckBoxes;
NSString *farmerCardNumber;
NSString *fName;
@implementation GlobalVars
{
}
@end
#1
32
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:
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:
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.
- 你不需要像这样使用全局变量;您应该能够创建一个模型对象,该对象是根据需要创建的,并引用它传递给视图。这是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.
- 您还发布了一个不相关问题的堆栈跟踪,这在Objective-C中非常常见;一旦你意识到它是什么,只有你能解决这个错误。
#2
4
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分配给farmerCardNumber而不是NSString。
For example, if you do something like
例如,如果你做了类似的事情
farmerCardNumber = [someDictionary objectForKey:@"someKey"];
and [someDictionary objectForKey:@"someKey"]
happens to be an array and not a string, then farmerCardNumber
points to that array, even if it was declared as pointer to a string.
并且[someDictionary objectForKey:@“someKey”]恰好是一个数组而不是一个字符串,那么farmerCardNumber指向该数组,即使它被声明为指向字符串的指针。
#3
0
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.
似乎你已经将可变数组传递给你的字符串varibale,这就是你得到那个错误的原因。
#4
0
I am using in all my project and working fine.
我在我的所有项目中使用并且工作正常。
GlobalResource.h
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
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
#5
-1
Remove the line
删除该行
#import "GlobalVars.h"
from GlobalVars.m.
来自GlobalVars.m。
#6
-1
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
Other.m
#import "GlobalVars1.h"
GlobalVars1.h
GlobalVars1.h
extern NSArray *truckBoxes;
extern NSArray *farmerlist;
extern NSString *farmerCardNumber;
extern NSString *fName;
GlobalVars.h
GlobalVars.h
#import <UIKit/UIKit.h>
@interface GlobalVars : NSObject
{
}
@end
GlobalVars.m
GlobalVars.m
#import "GlobalVars.h"
NSArray *farmerlist;
NSArray *truckBoxes;
NSString *farmerCardNumber;
NSString *fName;
@implementation GlobalVars
{
}
@end