繁体   English   中英

在Objective-C中使用全局变量

[英]Usage of global variables in 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;
}

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

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

建议创建不可变的全局变量,而不是行内字符串常量(难以重构且不进行编译时检查)或#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

暂无
暂无

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

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