简体   繁体   English

在Objective-C中使用全局变量

[英]Usage of global variables in Objective-C

What is the best practice to use global variables in Objective-C? 在Objective-C中使用全局变量的最佳实践是什么?

Right now I have a class .h/.m with all of the global variables and where common functions is declared like so: 现在,我有一个.h / .m类,其中包含所有全局变量,并且在其中声明通用函数的方式如下:

.h 。H

    BOOL  bOne; 
NSInteger iOne;
BOOL  bTwo;
BOOL  nThreee;

id NilOrValue(id aValue);
BOOL NSStringIsValidEmail(NSString *email);
BOOL NSStringIsValidName(NSString *name);
BOOL NSStringIsVaildUrl  ( NSString * candidate );
BOOL NSStringIsValidPhoneNumber( NSString *phoneNumber );
NSString *displayErrorCode( NSError *anError );
NSString *MacAdress ();
NSString* md5( NSString *str );

#define IS_IPHONE ( [[[UIDevice currentDevice] model] isEqualToString:@"iPhone"] )

#define IS_WIDESCREEN (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double) 568) < DBL_EPSILON)

#define IS_IPHONE_5 ( IS_WIDESCREEN )

#define kSettings [NSUserDefaults standardUserDefaults];

#define EMPTYIFNIL(foo) ((foo == nil) ? @"" : foo)

.m .m

   BOOL  bOne = NO; 
NSInteger iOne = 0; 
BOOL  bTwo = NO; 
BOOL  nThreee = NO; 


id NilOrValue(id aValue) {
    if ((NSNull *)aValue == [NSNull null]) {
        return nil;
    }
    else {
        return aValue;
    }
}

NSString* md5( NSString *str )
{
    // Create pointer to the string as UTF8
    const char *ptr = [str UTF8String];

    // Create byte array of unsigned chars
    unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];

    // Create 16 byte MD5 hash value, store in buffer
    CC_MD5(ptr, (CC_LONG)strlen(ptr), md5Buffer);

    // Convert MD5 value in the buffer to NSString of hex values
    NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x",md5Buffer[i]];

    return output;
}



BOOL NSStringIsVaildUrl  (NSString * candidate) {
    NSString *urlRegEx =
    @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
    NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx];
    return [urlTest evaluateWithObject:candidate];
}


BOOL NSStringIsValidEmail(NSString *email) {

    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    if (email.length == 0) {
        return YES;
    }else {
        if (![emailTest evaluateWithObject:email]) {
            return NO;
        }else {
            return YES;
        }
    }

}

BOOL NSStringIsValidName(NSString *name) {

    NSString *nameRegex = @"^([a-zA-Z'-]+)$";
    NSPredicate *nameTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", nameRegex];
    if (name.length == 0) {
        return YES;
    }else {
        if (![nameTest evaluateWithObject:name]) {
            return NO;
        } else {
            return YES;
        }
    }

}

BOOL NSStringIsValidPhoneNumber(NSString *phoneNumber) {

    NSError *error = NULL;
    NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypePhoneNumber error:&error];

    NSRange inputRange = NSMakeRange(0, [phoneNumber length]);
    NSArray *matches = [detector matchesInString:phoneNumber options:0 range:inputRange];

    // no match at all
    if ([matches count] == 0) {
        return NO;
    }

    // found match but we need to check if it matched the whole string
    NSTextCheckingResult *result = (NSTextCheckingResult *)[matches objectAtIndex:0];

    if ([result resultType] == NSTextCheckingTypePhoneNumber && result.range.location == inputRange.location && result.range.length == inputRange.length) {
        // it matched the whole string
        return YES;
    }
    else {
        // it only matched partial string
        return NO;
    }


}

NSString *MacAdress ()  {

    int                 mgmtInfoBase[6];
    char                *msgBuffer = NULL;
    size_t              length;
    unsigned char       macAddress[6];
    struct if_msghdr    *interfaceMsgStruct;
    struct sockaddr_dl  *socketStruct;
    NSString            *errorFlag = NULL;

    // Setup the management Information Base (mib)
    mgmtInfoBase[0] = CTL_NET;        // Request network subsystem
    mgmtInfoBase[1] = AF_ROUTE;       // Routing table info
    mgmtInfoBase[2] = 0;
    mgmtInfoBase[3] = AF_LINK;        // Request link layer information
    mgmtInfoBase[4] = NET_RT_IFLIST;  // Request all configured interfaces

    // With all configured interfaces requested, get handle index
    if ((mgmtInfoBase[5] = if_nametoindex("en0")) == 0)
        errorFlag = @"if_nametoindex failure";
    else
    {
        // Get the size of the data available (store in len)
        if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0)
            errorFlag = @"sysctl mgmtInfoBase failure";
        else
        {
            // Alloc memory based on above call
            if ((msgBuffer = malloc(length)) == NULL)
                errorFlag = @"buffer allocation failure";
            else
            {
                // Get system information, store in buffer
                if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0)
                    errorFlag = @"sysctl msgBuffer failure";
            }
        }
    }

    // Befor going any further...
    if (errorFlag != NULL)
    {
        NSLog(@"Error: %@", errorFlag);
          free(msgBuffer);
        return errorFlag;
    }

    // Map msgbuffer to interface message structure
    interfaceMsgStruct = (struct if_msghdr *) msgBuffer;

    // Map to link-level socket structure
    socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1);

    // Copy link layer address data in socket structure to an array
    memcpy(&macAddress, socketStruct->sdl_data + socketStruct->sdl_nlen, 6);

    // Read from char array into a string object, into traditional Mac address format
    NSString *macAddressString = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
                                  macAddress[0], macAddress[1], macAddress[2],
                                  macAddress[3], macAddress[4], macAddress[5]];
    NSLog(@"Mac Address: %@", macAddressString);

    // Release the buffer memory
    free(msgBuffer);

    return macAddressString;
}

Is this a bad solution? 这是一个不好的解决方案吗? If yes how would I manage to use my global variables in the best way? 如果是,我将如何以最佳方式使用全局变量?

Global variable always cause problem but in some scenario it is useful there are two type global variable we required one are constant second are those could change there value... 全局变量总是会引起问题,但是在某些情况下它很有用,我们需要两种类型的全局变量,一种是常量,第二种是可以改变值的变量...

the recommendation is to create immutable global variables instead of in-line string constants (hard to refactor and no compile-time checking) or #defines (no compile-time checking). 建议创建不可变的全局变量,而不是行内字符串常量(难以重构且不进行编译时检查)或#defines(不进行编译时检查)。 Here's how you might do so... 您可以按照以下方式进行操作...

in MyConstants.h: 在MyConstants.h中:

extern NSString * const MyStringConstant;

in MyConstants.m: 在MyConstants.m中:

NSString * const MyStringConstant = @"MyString";

then in any other .m file: 然后在任何其他.m文件中:

#import "MyConstants.h"

...
[someObject someMethodTakingAString:MyStringConstant];

... This way, you gain compile-time checking that you haven't mis-spelled a string constant, you can check for pointer equality rather than string equality[1] in comparing your constants, and debugging is easier, since the constants have a run-time string value. ...这样,您便获得了编译时检查,以确保您没有误拼写一个字符串常量,可以在比较常量时检查指针相等性而不是字符串相等性[1],并且由于常量,调试更容易具有运行时字符串值。

for mutable variables the safe way is adopting the singalton pattern 对于可变变量,安全的方法是采用singalton模式

@interface VariableStore : NSObject
{
    // Place any "global" variables here
}
// message from which our instance is obtained
+ (VariableStore *)sharedInstance;
@end

@implementation VariableStore
+ (VariableStore *)sharedInstance
{
    // the instance of this class is stored here
    static VariableStore *myInstance = nil;

    // check to see if an instance already exists
    if (nil == myInstance) {
        myInstance  = [[[self class] alloc] init];
        // initialize variables here
    }
    // return the instance of this class
    return myInstance;
}
@end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM