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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:36:19  来源:igfitidea点击:

Using global variables in Objective-C

iosobjective-cunrecognized-selector

提问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 farmerlistand truckBoxesfrom all over the app, but cant access fNameor farmerCardNumber.

我可以从整个应用程序访问farmerlisttruckBoxes,但无法访问fNamefarmerCardNumber

I can write to farmerCardNumberand 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 NSMutableArrayto farmerCardNumberinstead of a NSString.

表示您在代码中的某处分配了NSMutableArraytofarmerCardNumber而不是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 farmerCardNumberpoints 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