Ios 在Objective-C中使用全局变量

Ios 在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;

首先,我尝试了stackoverflow中给出的几乎所有解决方案,但没有成功实现全局VAR,我甚至做了一个分步教程,但仍然会遇到相同的错误

问题是:

我有一个有几个视图的程序,我想在所有视图上使用变量, 所以我使用了全局变量

我有:

GlobalVars.h

#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极为常见的无关问题的堆栈跟踪;只有在您意识到它是什么后,才能修复此错误

我在我所有的项目中都使用了它,并且工作得很好

GlobalResource.h

#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