在Objective-C中使用全局变量

时间:2013-11-23 11:22:06

标签: ios iphone objective-c

在Objective-C中使用全局变量的最佳做法是什么?

现在我有一个带有所有全局变量的类.h / .m,以及如下所示的常用函数:

·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

   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;
}

这是一个糟糕的解决方案吗?如果是,我将如何以最佳方式设法使用我的全局变量?

1 个答案:

答案 0 :(得分:0)

全局变量总是会导致问题,但在某些情况下,有两种类型的全局变量是有用的,我们需要一个是常量的第二个是那些可以改变它的值......

建议创建不可变的全局变量而不是内联字符串常量(难以重构和无编译时检查)或#defines(无编译时检查)。你可以这样做......

在MyConstants.h中

extern NSString * const MyStringConstant;
MyConstants.m中的

NSString * const MyStringConstant = @"MyString";

然后在任何其他.m文件中:

#import "MyConstants.h"

...
[someObject someMethodTakingAString:MyStringConstant];

... 这样,你获得编译时检查,你没有拼错字符串常量,你可以在比较你的常量时检查指针相等而不是字符串相等[1],并且调试更容易,因为常量有一个运行时间字符串值。

对于可变变量,安全方式是采用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