封裝iOS開發(fā)常用方法(持續(xù)更新)

//根據(jù)日期算出周幾

    + (NSString*)weekdayStringFromDate:(NSDate*)inputDate
    {
        NSArray *weekdays = [NSArray arrayWithObjects: [NSNull null], @"周日", @"周一", @"周二", @"周三", @"周四", @"周五", @"周六", nil];
        NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        NSTimeZone *timeZone = [[NSTimeZone alloc] initWithName:@"Asia/Shanghai"];
        [calendar setTimeZone: timeZone];
        NSCalendarUnit calendarUnit = NSWeekdayCalendarUnit;
        NSDateComponents *theComponents = [calendar components:calendarUnit fromDate:inputDate];
    
    return [weekdays objectAtIndex:theComponents.weekday];
    }
//轉化為時間字符串

    + (NSString *)dateStringFromNumberTimer:(NSString *)timerStr {
        //轉化為Double
        double t = [timerStr doubleValue];
        //計算出距離1970的NSDate
        NSDate *date = [NSDate dateWithTimeIntervalSince1970:t];
        //轉化為 時間格式化字符串
        //NSDateFormatter *df = [[[NSDateFormatter alloc] init] autorelease];
        
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        df.dateFormat = @"yyyy-MM-dd HH:mm:ss";
        //轉化為 時間字符串
        return [df stringFromDate:date];
    }
//動態(tài) 計算行高
//根據(jù)字符串的實際內容的多少 在固定的寬度和字體的大小肤视,動態(tài)的計算出實際的高度

    + (CGFloat)textHeightFromTextString:(NSString *)text width:(CGFloat)textWidth fontSize:(CGFloat)size{
        if ([MZLUtility getCurrentIOS] >= 7.0) {
            //iOS7之后
            /*
             第一個參數(shù): 預設空間 寬度固定  高度預設 一個最大值
             第二個參數(shù): 行間距 如果超出范圍是否截斷
             第三個參數(shù): 屬性字典 可以設置字體大小
             */
            NSDictionary *dict = @{NSFontAttributeName:[UIFont systemFontOfSize:size]};
            CGRect rect = [text boundingRectWithSize:CGSizeMake(textWidth, MAXFLOAT) options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];
            //返回計算出的行高
            return rect.size.height;
            
        }else {
            //iOS7之前
            /*
             1.第一個參數(shù)  設置的字體固定大小
             2.預設 寬度和高度 寬度是固定的 高度一般寫成最大值
             3.換行模式 字符換行
             */
            CGSize textSize = [text sizeWithFont:[UIFont systemFontOfSize:size] constrainedToSize:CGSizeMake(textWidth, MAXFLOAT) lineBreakMode:NSLineBreakByCharWrapping];
            return textSize.height;//返回 計算出得行高
        }
    }
//獲取iOS版本號

    + (double)getCurrentIOS {
        return [[[UIDevice currentDevice] systemVersion] doubleValue];
    }
    + (CGSize)getScreenSize {
        return [[UIScreen mainScreen] bounds].size;
    }
//獲得當前系統(tǒng)時間到指定時間的時間差字符串,傳入目標時間字符串和格式

    +(NSString*)stringNowToDate:(NSString*)toDate formater:(NSString*)formatStr
    {
    
    NSDateFormatter *formater=[[NSDateFormatter alloc] init];
    if (formatStr) {
        [formater setDateFormat:formatStr];
    }
    else{
        [formater setDateFormat:[NSString stringWithFormat:@"yyyy-MM-dd HH:mm:ss"]];
    }
    NSDate *date=[formater dateFromString:toDate];
    
    return [self stringNowToDate:date];
    
    }
//獲得到指定時間的時間差字符串,格式在此方法內返回前自己根據(jù)需要格式化

    +(NSString*)stringNowToDate:(NSDate*)toDate
    {
        //創(chuàng)建日期 NSCalendar對象
        NSCalendar *cal = [NSCalendar currentCalendar];
        //得到當前時間
        NSDate *today = [NSDate date];
        
    //用來得到具體的時差,位運算
    unsigned int unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ;
    
    if (toDate && today) {//不為nil進行轉化
        NSDateComponents *d = [cal components:unitFlags fromDate:today toDate:toDate options:0 ];
        
        //NSString *dateStr=[NSString stringWithFormat:@"%d年%d月%d日%d時%d分%d秒",[d year],[d month], [d day], [d hour], [d minute], [d second]];
        NSString *dateStr=[NSString stringWithFormat:@"%02ld:%02ld:%02ld",[d hour], [d minute], [d second]];
        return dateStr;
    }
    return @"";
    }
//獲取 一個文件 在沙盒Library/Caches/ 目錄下的路徑

    + (NSString *)getFullPathWithFile:(NSString *)urlName {
    
    //先獲取 沙盒中的Library/Caches/路徑
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *myCacheDirectory = [docPath stringByAppendingPathComponent:@"MyCaches"];
    //檢測MyCaches 文件夾是否存在
    if (![[NSFileManager defaultManager] fileExistsAtPath:myCacheDirectory]) {
        //不存在 那么創(chuàng)建
        [[NSFileManager defaultManager] createDirectoryAtPath:myCacheDirectory withIntermediateDirectories:YES attributes:nil error:nil];
    }
    //用md5進行 加密 轉化為 一串十六進制數(shù)字 (md5加密可以把一個字符串轉化為一串唯一的用十六進制表示的串)
    NSString * newName = MD5Hash(urlName);
    
    //拼接路徑
    return [myCacheDirectory stringByAppendingPathComponent:newName];
    }
//檢測 緩存文件 是否超時

    + (BOOL)isTimeOutWithFile:(NSString *)filePath timeOut:(double)timeOut {
        //獲取文件的屬性
        NSDictionary *fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
        //獲取文件的上次的修改時間
        NSDate *lastModfyDate = fileDict.fileModificationDate;
        //算出時間差 獲取當前系統(tǒng)時間 和 lastModfyDate時間差
        NSTimeInterval sub = [[NSDate date] timeIntervalSinceDate:lastModfyDate];
        if (sub < 0) {
            sub = -sub;
        }
        //比較是否超時
        if (sub > timeOut) {
            //如果時間差 大于 設置的超時時間 那么就表示超時
            return YES;
        }
        return NO;
    }
//清除緩存

    + (void) resetCache {
        [[NSFileManager defaultManager] removeItemAtPath:[MZLCache cacheDirectory] error:nil];
    }
//緩存目錄

    + (NSString*) cacheDirectory {
        NSArray* paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        NSString *cacheDirectory = [paths objectAtIndex:0];
        cacheDirectory = [cacheDirectory stringByAppendingPathComponent:@"MZLCaches"];
        return cacheDirectory;
    }
//刪除指定的緩存

    + (NSData*) objectForKey:(NSString*)key {
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *filename = [self.cacheDirectory stringByAppendingPathComponent:key];
        
        if ([fileManager fileExistsAtPath:filename])
        {
            NSDate *modificationDate = [[fileManager attributesOfItemAtPath:filename error:nil] objectForKey:NSFileModificationDate];
            if ([modificationDate timeIntervalSinceNow] > cacheTime) {
                [fileManager removeItemAtPath:filename error:nil];
            } else {
                NSData *data = [NSData dataWithContentsOfFile:filename];
                return data;
            }
        }
        return nil;
    }
//創(chuàng)建指定緩存

    + (void) setObject:(NSData*)data forKey:(NSString*)key {
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *filename = [self.cacheDirectory stringByAppendingPathComponent:key];
        
        BOOL isDir = YES;
        if (![fileManager fileExistsAtPath:self.cacheDirectory isDirectory:&isDir]) {
            [fileManager createDirectoryAtPath:self.cacheDirectory withIntermediateDirectories:NO attributes:nil error:nil];
        }
        
        NSError *error;
        @try {
            [data writeToFile:filename options:NSDataWritingAtomic error:&error];
        }
        @catch (NSException * e) {
            //TODO: error handling maybe
        }
    }
// 獲取某個路徑下文件大小

    + (long long) fileSizeAtPath:(NSString*) filePath{
        
        NSFileManager* manager = [NSFileManager defaultManager];
        if ([manager fileExistsAtPath:filePath]){
            
        return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
    }
    return 0;
    
    }
// 獲取緩存大小

    + (float ) folderSizeAtPath:(NSString*) folderPath{
        NSFileManager* manager = [NSFileManager defaultManager];
        if (![manager fileExistsAtPath:folderPath])
            return 0;
        NSEnumerator *childFilesEnumerator = [[manager subpathsAtPath:folderPath] objectEnumerator];
        NSString* fileName;
        long long folderSize = 0;
        while ((fileName = [childFilesEnumerator nextObject]) != nil){
            NSString* fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];
            folderSize += [MZLCache fileSizeAtPath:fileAbsolutePath];
        }
        return folderSize/(1024.0*1024.0);
    }
//MD5加密字符串

    NSString * MD5Hash(NSString *aString) {
        const char *cStr = [aString UTF8String];
        unsigned char result[16];
        CC_MD5( cStr, (CC_LONG)strlen(cStr), result );
        return [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
                result[0], result[1], result[2], result[3],
                result[4], result[5], result[6], result[7],
                result[8], result[9], result[10], result[11],
                result[12], result[13], result[14], result[15]];
    }
/**
 *  手機號碼驗證
 *
 *  @param mobileNumbel 傳入的手機號碼
 *
 *  @return 格式正確返回true  錯誤 返回fals
 */
+ (BOOL)isMobileNumber:(NSString *)mobileNum
{
    /**
     * 手機號碼
     * 移動:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
     * 聯(lián)通:130,131,132,152,155,156,185,186
     * 電信:133,1349,153,180,189,181(增加)
     * 新增:14_,17_
     */
    NSString * MOBIL = @"^1(3[0-9]|4[0-9]|5[0-35-9]|7[0-9]|8[025-9])\\d{8}$";
    /**
     10         * 中國移動:China Mobile
     11         * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
     12         */
    NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[2378])\\d)\\d{7}$";
    /**
     15         * 中國聯(lián)通:China Unicom
     16         * 130,131,132,152,155,156,185,186
     17         */
    NSString * CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$";
    /**
     20         * 中國電信:China Telecom
     21         * 133,1349,153,180,189,181(增加)
     22         */
    NSString * CT = @"^1((33|53|8[019])[0-9]|349)\\d{7}$";
    /**
     25         * 大陸地區(qū)固話及小靈通
     26         * 區(qū)號:010,020,021,022,023,024,025,027,028,029
     27         * 號碼:七位或八位
     28         */
    // NSString * PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
    
    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBIL];
    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
    
    if (([regextestmobile evaluateWithObject:mobileNum]
         || [regextestcm evaluateWithObject:mobileNum]
         || [regextestct evaluateWithObject:mobileNum]
         || [regextestcu evaluateWithObject:mobileNum])) {
        return YES;
    }
    
    return NO;
}
/**
 *  密碼驗證
 *
 *  @param password 傳入的密碼 6-16位 大小寫數(shù)字
 *
 *  @return 格式正確返回true  錯誤 返回fals
 */
+ (BOOL)isPassword:(NSString *)password
{
    
    NSRegularExpression *regularexpression = [[NSRegularExpression alloc]
                                              initWithPattern:@"^[a-zA-Z0-9]{6,16}$"
                                              options:NSRegularExpressionCaseInsensitive
                                              error:nil];
    NSUInteger numberofMatch = [regularexpression numberOfMatchesInString:password
                                                                  options:NSMatchingReportProgress
                                                                    range:NSMakeRange(0, password.length)];
    if(numberofMatch > 0)
        return YES;
    return NO;
}
/**
 *  郵箱驗證
 *
 *  @param email 傳入的郵箱
 *
 *  @return 格式正確返回true  錯誤 返回fals
 */
+ (BOOL) isEmail:(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 ([emailTest evaluateWithObject:email]) {
        
        return YES;
    }
    return NO;
}

/**
 *  身份證號驗證
 *
 *  @param identityCard 傳入的身份證號
 *
 *  @return 格式正確返回true  錯誤 返回fals
 */
+ (BOOL) isIdentityCard: (NSString *)identityCard
{
    
    NSString *idnum = @"^(\\d{14}|\\d{17})(\\d|[xX])$";
    
    NSPredicate *identityCardPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",idnum];
    
    return [identityCardPredicate evaluateWithObject:identityCard];
}

/** 銀行卡號有效性問題Luhn算法
 *  現(xiàn)行 16 位銀聯(lián)卡現(xiàn)行卡號開頭 6 位是 622126~622925 之間的摇予,7 到 15 位是銀行自定義的,
 *  可能是發(fā)卡分行庶喜,發(fā)卡網(wǎng)點救鲤,發(fā)卡序號秩冈,第 16 位是校驗碼。
 *  16 位卡號校驗位采用 Luhm 校驗方法計算:
 *  1丹锹,將未帶校驗位的 15 位卡號從右依次編號 1 到 15芬失,位于奇數(shù)位號上的數(shù)字乘以 2
 *  2,將奇位乘積的個十位全部相加租漂,再加上所有偶數(shù)位上的數(shù)字
 *  3,將加法和加上校驗位能被 10 整除秃踩。
 */
+ (BOOL) isBankCardluhmCheck:(NSString *)bankNumber
{
    NSString * lastNum = [[bankNumber substringFromIndex:(bankNumber.length-1)] copy];//取出最后一位
    NSString * forwardNum = [[bankNumber substringToIndex:(bankNumber.length -1)] copy];//前15或18位
    
    NSMutableArray * forwardArr = [[NSMutableArray alloc] initWithCapacity:0];
    for (int i=0; i<forwardNum.length; i++) {
        NSString * subStr = [forwardNum substringWithRange:NSMakeRange(i, 1)];
        [forwardArr addObject:subStr];
    }
    
    NSMutableArray * forwardDescArr = [[NSMutableArray alloc] initWithCapacity:0];
    for (int i = (int)(forwardArr.count-1); i> -1; i--) {//前15位或者前18位倒序存進數(shù)組
        [forwardDescArr addObject:forwardArr[i]];
    }
    
    NSMutableArray * arrOddNum = [[NSMutableArray alloc] initWithCapacity:0];//奇數(shù)位*2的積 < 9
    NSMutableArray * arrOddNum2 = [[NSMutableArray alloc] initWithCapacity:0];//奇數(shù)位*2的積 > 9
    NSMutableArray * arrEvenNum = [[NSMutableArray alloc] initWithCapacity:0];//偶數(shù)位數(shù)組
    
    for (int i=0; i< forwardDescArr.count; i++) {
        NSInteger num = [forwardDescArr[i] intValue];
        if (i%2) {//偶數(shù)位
            [arrEvenNum addObject:[NSNumber numberWithInteger:num]];
        }else{//奇數(shù)位
            if (num * 2 < 9) {
                [arrOddNum addObject:[NSNumber numberWithInteger:num * 2]];
            }else{
                NSInteger decadeNum = (num * 2) / 10;
                NSInteger unitNum = (num * 2) % 10;
                [arrOddNum2 addObject:[NSNumber numberWithInteger:unitNum]];
                [arrOddNum2 addObject:[NSNumber numberWithInteger:decadeNum]];
            }
        }
    }
    
    __block  NSInteger sumOddNumTotal = 0;
    [arrOddNum enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        sumOddNumTotal += [obj integerValue];
    }];
    
    
    __block NSInteger sumOddNum2Total = 0;
    [arrOddNum2 enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        sumOddNum2Total += [obj integerValue];
    }];
    
    __block NSInteger sumEvenNumTotal = 0 ;
    [arrEvenNum enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        sumEvenNumTotal += [obj integerValue];
    }];
    
    
    NSInteger lastNumber = [lastNum integerValue];
    
    NSInteger luhmTotal = lastNumber + sumEvenNumTotal + sumOddNum2Total + sumOddNumTotal;
    
    return (luhmTotal%10 ==0)?YES:NO;
}

//驗證手機號的合法性
+(BOOL)isValidateMobile:(NSString *)mobile
{
    //手機號以13, 15蒜胖,18開頭台谢,八個 \d 數(shù)字字符
    NSString *phoneRegex = @"^((13[0-9])|(15[^4,\\D])|(18[0,0-9]))\\d{8}$";
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",phoneRegex];
    //    NSLog(@"phoneTest is %@",phoneTest);
    return [phoneTest evaluateWithObject:mobile];
}

/**
 * 驗證車牌號
 */
+ (BOOL) checkCarNumber:(NSString *) CarNumber
{
    NSString *bankNum = @"^[\u4e00-\u9fa5]{1}[a-zA-Z]{1}[a-zA-Z_0-9]{4}[a-zA-Z_0-9_\u4e00-\u9fa5]$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",bankNum];
    BOOL isMatch = [pred evaluateWithObject:CarNumber];
    return isMatch;
}

/**
 * 驗證17位車架號
 */
+ (BOOL) checkCheJiaNumber:(NSString *) CheJiaNumber
{
    NSString *bankNum=@"^(\\d{17})$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",bankNum];
    BOOL isMatch = [pred evaluateWithObject:CheJiaNumber];
    return isMatch;
}
/**
 * 驗證只能輸入數(shù)字和字母
 */
+ (BOOL) checkTeshuZifuNumber:(NSString *) CheJiaNumber
{
    NSString *bankNum=@"^[A-Za-z0-9]+$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",bankNum];
    BOOL isMatch = [pred evaluateWithObject:CheJiaNumber];
    return isMatch;
}
/**
 * 驗證以C開頭字符
 */
+ (BOOL) checkCtooNumber:(NSString *) nickNumber{
    NSString *nickNum=@"^C{1}[0-9]+$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",nickNum];
    BOOL isMatch = [pred evaluateWithObject:nickNumber];
    return isMatch;
}
/**
 * 驗證以C開頭的18位字符
 */
+ (BOOL) checkCtooNumberTo18:(NSString *) nickNumber
{
    NSString *nickNum=@"^C{1}[0-9]{18}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",nickNum];
    BOOL isMatch = [pred evaluateWithObject:nickNumber];
    return isMatch;
}
/**
 * 驗證昵稱
 */
+ (BOOL) checkNickname:(NSString *) nickname
{
    NSString *nicknameRegex = @"^[\u4e00-\u9fa5]{4,8}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",nicknameRegex];
    BOOL isMatch = [pred evaluateWithObject:nickname];
    return isMatch;
}
/**
 * 驗證URL
 */
+ (BOOL)checkURL : (NSString *) url
{
    NSString *pattern = @"^[0-9A-Za-z]{1,50}";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
    BOOL isMatch = [pred evaluateWithObject:url];
    return isMatch;
}
/**
 * 驗證員工號,12位的數(shù)字
 */
+ (BOOL)checkEmployeeNumber : (NSString *) number
{
    NSString *pattern = @"^[0-9]{12}";
    
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
    BOOL isMatch = [pred evaluateWithObject:number];
    return isMatch;
}
/**
 * 驗證用戶姓名,20位的中文或英文
 */
+ (BOOL)checkUserName : (NSString *) userName
{
    //    NSString *pattern = @"^[A-Za-z0-9]{6,20}+$";
    NSString *pattern = @"^([\u4e00-\u9fa5]+|([a-zA-Z]+\s?)+)$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
    BOOL isMatch = [pred evaluateWithObject:userName];
    return isMatch;
}
/**
 * model轉字典
 */
- (NSDictionary *)dictionaryFromModel
{
    unsigned int count = 0;
    
    objc_property_t *properties = class_copyPropertyList([self class], &count);
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:count];
    
    for (int i = 0; i < count; i++) {
        NSString *key = [NSString stringWithUTF8String:property_getName(properties[i])];
        id value = [self valueForKey:key];
        
        //only add it to dictionary if it is not nil
        if (key && value) {
            if ([value isKindOfClass:[NSString class]]
                || [value isKindOfClass:[NSNumber class]]) {
                // 普通類型的直接變成字典的值
                [dict setObject:value forKey:key];
            }
            else if ([value isKindOfClass:[NSArray class]]
                     || [value isKindOfClass:[NSDictionary class]]) {
                // 數(shù)組類型或字典類型
                [dict setObject:[self idFromObject:value] forKey:key];
            }
            else {
                // 如果model里有其他自定義模型荆虱,則遞歸將其轉換為字典
                [dict setObject:[value dictionaryFromModel] forKey:key];
            }
        } else if (key && value == nil) {
            // 如果當前對象該值為空怀读,設為nil骑脱。在字典中直接加nil會拋異常,需要加NSNull對象
            [dict setObject:[NSNull null] forKey:key];
        }
    }
    
    free(properties);
    return dict;
}
/**
 * 字典 轉 model
 */
+ (instancetype)objectWithDictionary:(NSDictionary *)dictionary
{
    id obj = [[self alloc] init];
    
    // 獲取所有的成員變量
    unsigned int count;
    Ivar *ivars = class_copyIvarList(self, &count);
    
    for (unsigned int i = 0; i < count; i++)
    {
        Ivar ivar = ivars[i];
        
        // 取出的成員變量啤誊,去掉下劃線
        NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)];
        NSString *key = [ivarName substringFromIndex:1];
        
        id value = dictionary[key];
        
        // 當這個值為空時拥娄,判斷一下是否執(zhí)行了replacedKeyFromPropertyName協(xié)議,如果執(zhí)行了替換原來的key查值
        if (!value)
        {
            if ([self respondsToSelector:@selector(replacedKeyFromPropertyName)])
            {
                NSString *replaceKey = [self replacedKeyFromPropertyName][key];
                value = dictionary[replaceKey];
            }
        }
        
        // 字典嵌套字典
        if ([value isKindOfClass:[NSDictionary class]])
        {
            NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
            NSRange range = [type rangeOfString:@"\""];
            type = [type substringFromIndex:range.location + range.length];
            range = [type rangeOfString:@"\""];
            type = [type substringToIndex:range.location];
            Class modelClass = NSClassFromString(type);
            
            if (modelClass)
            {
                value = [modelClass objectWithDictionary:value];
            }
        }
        
        // 字典嵌套數(shù)組
        if ([value isKindOfClass:[NSArray class]])
        {
            if ([self respondsToSelector:@selector(objectClassInArray)])
            {
                NSMutableArray *models = [NSMutableArray array];
                
                NSString *type = [self objectClassInArray][key];
                Class classModel = NSClassFromString(type);
                for (NSDictionary *dict in value)
                {
                    id model = [classModel objectWithDictionary:dict];
                    [models addObject:model];
                }
                value = models;
            }
        }
        if (value)
        {
            [obj setValue:value forKey:key];
        }
    }
    
    // 釋放ivars
    free(ivars);
    
    return obj;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市丢烘,隨后出現(xiàn)的幾起案子些椒,更是在濱河造成了極大的恐慌,老刑警劉巖赢乓,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骏全,死亡現(xiàn)場離奇詭異,居然都是意外死亡姜贡,警方通過查閱死者的電腦和手機楼咳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來余耽,“玉大人苹熏,你說我怎么就攤上這事「さⅲ” “怎么了干发?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長冀续。 經(jīng)常有香客問我,道長尺锚,這世上最難降的妖魔是什么桐罕? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮溅潜,結果婚禮上,老公的妹妹穿的比我還像新娘粗仓。我一直安慰自己,他們只是感情好塘淑,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布蚂斤。 她就那樣靜靜地躺著,像睡著了一般捌治。 火紅的嫁衣襯著肌膚如雪纽窟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天森枪,我揣著相機與錄音县袱,去河邊找鬼瓷胧。 笑死,一個胖子當著我的面吹牛搓萧,可吹牛的內容都是我干的。 我是一名探鬼主播揍移,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼那伐,長吁一口氣:“原來是場噩夢啊……” “哼石蔗!你這毒婦竟也來了?” 一聲冷哼從身側響起诉探,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤棍厌,失蹤者是張志新(化名)和其女友劉穎竖席,沒想到半個月后敬肚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡憎亚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年虽填,在試婚紗的時候發(fā)現(xiàn)自己被綠了曹动。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡恶守,死狀恐怖贡必,靈堂內的尸體忽然破棺而出仔拟,到底是詐尸還是另有隱情,我是刑警寧澤利花,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布炒事,位于F島的核電站,受9級特大地震影響权薯,放射性物質發(fā)生泄漏睡扬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一刁俭、第九天 我趴在偏房一處隱蔽的房頂上張望韧涨。 院中可真熱鬧,春花似錦如孝、人聲如沸娩贷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽储笑。三九已至,卻和暖如春腔稀,著一層夾襖步出監(jiān)牢的瞬間羽历,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工诵闭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留澎嚣,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓润歉,卻偏偏與公主長得像颈抚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子驱富,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內容