「 iOS知识小集 」2018 · 第 29 期

栏目: IOS · 发布时间: 6年前

内容简介:本周我们启动主题收集,如果你有想了解的 iOS 技术方面的主题,请在我们的 github另外,我们的小程序

原文链接

本周我们启动主题收集,如果你有想了解的 iOS 技术方面的主题,请在我们的 github https://github.com/awesome-tips/iOS-Tips/ 提 issue,也可以在相关的 issue 推荐文章。我们后期会每周整理一个主题。

另外,我们的小程序 猿小荐 正式发布,我们希望为大家提供一个良好的职位发布和查看工具,后期也会不断加入其它功能,欢迎大家试用。我们在后面的每篇文章中,也会加入一个职位推荐。

上周公众号发布的以下文章:

本期知识小集的主要内容包括:

  • 一入IAP深似海
  • iOS 金额字符串格式化显示的方法
  • 几个第三方框架关于线程锁的封装小技巧

一入IAP深似海

作者:高老师很忙

在做 IAP 的时候,我们通常会给 SKMutablePayment 对象的 applicationUsername 传入一个值,比如说用户ID的哈希值,等交易成功后,通过 transaction.payment.applicationUsername 与之前传入的值进行对比校验。

最近发现,交易成功回调返回的 transaction.payment.applicationUsername 有可能返回空,并且测试阶段很难发现。解决办法就是增加异常处理逻辑,当 transaction.payment.applicationUsername 返回空的时候,要加入一些业务相关的逻辑判断。例如,你的 applicationUsername 传入的是用户ID相关的信息,当 transaction.payment.applicationUsername 返回为空的时候,就要增加判断发生购买行为和收到回调时是否是同一个用户的逻辑,或者根据你具体的业务而定补充逻辑。

iOS 金额字符串格式化显示的方法

作者:KANGZUBIN

在一些金融类的 App 中,对于表示金额类的字符串,通常需要进行格式化后再显示出来。例如:

  • 0 --> 0.00
  • 123 --> 123.00
  • 123.456 --> 123.46
  • 102000 --> 102,000.00
  • 10204500 --> 10,204,500.00

它的规则如下:

个位数起每隔三位数字添加一个逗号,同时保留两位小数,也称为“千分位格式”。

我们一开始采取了一种比较笨拙的处理方式如下:

首先根据小数点 . 将传入的字符串分割为两部分,整数部分和小数部分(如果没有小数点,则补 .00 ,如果有多个小数点则报金额格式错误)。对于小数部分,只取前两位;然后对整数部分字符串进行遍历,从右到左,每三位数前插入一个逗号 , ,最后再把两部分拼接起来,代码大致如下:

- (NSString *)moneyFormat:(NSString *)money {
    if (!money || money.length == 0) {
        return money;
    }

    BOOL hasPoint = NO;
    if ([money rangeOfString:@"."].length > 0) {
        hasPoint = YES;
    }

    NSMutableString *pointMoney = [NSMutableString stringWithString:money];
    if (hasPoint == NO) {
        [pointMoney appendString:@".00"];
    }

    NSArray *moneys = [pointMoney componentsSeparatedByString:@"."];
    if (moneys.count > 2) {
        return pointMoney;
    } else if (moneys.count == 1) {
        return [NSString stringWithFormat:@"%@.00", moneys[0]];
    } else {
        // 整数部分每隔 3 位插入一个逗号
        NSString *frontMoney = [self stringFormatToThreeBit:moneys[0]];
        if ([frontMoney isEqualToString:@""]) {
            frontMoney = @"0";
        }
        // 拼接整数和小数两部分
        NSString *backMoney = moneys[1];
        if ([backMoney length] == 1) {
            return [NSString stringWithFormat:@"%@.%@0", frontMoney, backMoney];
        } else if ([backMoney length] > 2) {
            return [NSString stringWithFormat:@"%@.%@", frontMoney, [backMoney substringToIndex:2]];
        } else {
            return [NSString stringWithFormat:@"%@.%@", frontMoney, backMoney];
        }
    }
}
复制代码

其中, stringFormatToThreeBit: 方法的实现如下:

- (NSString *)stringFormatToThreeBit:(NSString *)string {
    NSString *tempString = [string stringByReplacingOccurrencesOfString:@"," withString:@""];
    NSMutableString *mutableString = [NSMutableString stringWithString:tempString];
    NSInteger n = 2;
    for (NSInteger i = tempString.length - 3; i > 0; i--) {
        n++;
        if (n == 3) {
            [mutableString insertString:@"," atIndex:i];
            n = 0;
        }
    }
    return mutableString;
}
复制代码

上述实现看起来非常繁琐。

其实,苹果提供了 NSNumberFormatter 用来处理 NSStringNSNumber 之间的转化,可以满足基本的数字形式的格式化。我们通过设置 NSNumberFormatternumberStylepositiveFormat 属性,即可实现上述功能,非常简洁,代码如下:

- (NSString *)formatDecimalNumber:(NSString *)string {
    if (!string || string.length == 0) {
        return string;
    }
    
    NSNumber *number = @([string doubleValue]);
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    formatter.numberStyle = kCFNumberFormatterDecimalStyle;
    formatter.positiveFormat = @"###,##0.00";
    
    NSString *amountString = [formatter stringFromNumber:number];
    return amountString;
}
复制代码

关于 NSNumberFormatter 更详细的用法,可以参考这篇文章的介绍: NSNumberFormatter 介绍和用法

几个第三方框架关于线程锁的封装小技巧

作者:陈满iOS

启示

第三方库中经常用到的这个小技巧,例如 YYCacheSDWebImage 等等,虽然各自封装的具体形式不太一样。

  • YYCache
「 iOS知识小集 」2018 · 第 29 期
  • SDWebImage
「 iOS知识小集 」2018 · 第 29 期
  • YYWebImage
「 iOS知识小集 」2018 · 第 29 期

我们可以借鉴到自己的项目中,在适当的位置通过宏来加锁解锁操作。

使用

1. YYCache 版本的宏封装

#define Lock() dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER)
#define Unlock() dispatch_semaphore_signal(self->_lock)
复制代码
  • 操作数据之前,先外面进行加锁解锁
- (NSInteger)totalCount {
	Lock();
	int count = [_kv getItemsCount];
	Unlock();
	return count;
}
复制代码
  • 锁里面再进行真正的数据操作
- (int)getItemsCount {
	return [self _dbGetTotalItemCount];
}
复制代码

2. SDWebImage版本的宏封装

  • 定义
#define LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#define UNLOCK(lock) dispatch_semaphore_signal(lock);
复制代码
  • 调用示例
- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field {
	LOCK(self.headersLock);
	if (value) {
		self.HTTPHeaders[field] = value;
	} else {
		[self.HTTPHeaders removeObjectForKey:field];
	}
	UNLOCK(self.headersLock);
}
复制代码

其中, self.headersLock 的定义为:

@property (strong, nonatomic, nonnull) dispatch_semaphore_t headersLock; 
复制代码

3. YYWebImage版本的宏封装

相对于上面,还有更方便的宏封装,把解锁操作跟加锁封装在一块。

  • 宏定义
#define LOCK(...) dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER); \
__VA_ARGS__; \
dispatch_semaphore_signal(self->_lock);

#define LOCK_VIEW(...) dispatch_semaphore_wait(view->_lock, DISPATCH_TIME_FOREVER); \
__VA_ARGS__; \
dispatch_semaphore_signal(view->_lock);
复制代码
  • 使用示例
- (void)didReceiveMemoryWarning:(NSNotification *)notification {
	[_requestQueue cancelAllOperations];
	[_requestQueue addOperationWithBlock: ^{
		_incrBufferCount = -60 - (int)(arc4random() % 120); // about 1~3 seconds to grow back..
		NSNumber *next = @((_curIndex + 1) % _totalFrameCount);
		LOCK(NSArray * keys = _buffer.allKeys;
			for (NSNumber * key in keys) {
				if (![key isEqualToNumber:next]) { // keep the next frame for smoothly animation
					[_buffer removeObjectForKey:key];
				}
			}
		)//LOCK
	}];
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Writing Windows VxDs and Device Drivers, Second Edition

Writing Windows VxDs and Device Drivers, Second Edition

Karen Hazzah / CMP / 1996-01-12 / USD 54.95

Software developer and author Karen Hazzah expands her original treatise on device drivers in the second edition of "Writing Windows VxDs and Device Drivers." The book and companion disk include the a......一起来看看 《Writing Windows VxDs and Device Drivers, Second Edition》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具