IOS知识点-小技巧-小笔记(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 保存到相册的老的方法 注意回调函数的写法 必须固定格式
let saveBool = UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(newURL!.path)
if saveBool == true{
// UISaveVideoAtPathToSavedPhotosAlbum(newURL!.path, self, nil, nil)
UISaveVideoAtPathToSavedPhotosAlbum(newURL!.path, self, #selector(self.image(image:didFinishSavingWithError:contextInfo:)), nil)
}
func image(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo:UnsafeRawPointer) {
if error == nil {
printLog("保存成功")
} else {
printLog("保存失败\(error)")
}
}
1
2
3
4
5
6
//跳转到appstore
// let str = "http://itunes.apple.com/cn/app/id966492118?mt=8" // 可直接跳转到appstore
// let str = "itms://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=966492118" //跳转到itunes Store 也会定位到应用
let str = "itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=966492118"//跳转到评分页 appstore
let url = URL(string: str)
UIApplication.shared.openURL(url!)

忽略 “Undeclared selector…” 的 Warning

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (_delegate && [_delegate respondsToSelector:@selector(retrievingProgressMP4:)])
{
[_delegate performSelector:@selector(retrievingProgressMP4:) withObject:[NSNumber numberWithFloat:_exportSession.progress]];
// NSLog(@"Effect Progress: %f", exportSession.progress);
}
// 方法没有显示声明 ,会报一个警告, 可以这样局部去除, 局部去除比较合适
//忽略 "Undeclared selector..." 的 Warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
// 需要禁用警告的代码
#pragma clang diagnostic pop

将GIF图片分解成多张PNG图片,使用UIImageView播放。

需要导入#import

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:@"<#gifName#>" withExtension:@"gif"]; //加载GIF图片
CGImageSourceRef gifSource = CGImageSourceCreateWithURL((CFURLRef) fileUrl, NULL); //将GIF图片转换成对应的图片源
size_t frameCout = CGImageSourceGetCount(gifSource); //获取其中图片源个数,即由多少帧图片组成
NSMutableArray *frames = [[NSMutableArray alloc] init]; //定义数组存储拆分出来的图片
for (size_t i = 0; i < frameCout; i++) {
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(gifSource, i, NULL); //从GIF图片中取出源图片
UIImage *imageName = [UIImage imageWithCGImage:imageRef]; //将图片源转换成UIimageView能使用的图片源
[frames addObject:imageName]; //将图片加入数组中
CGImageRelease(imageRef);
}
UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:CGRectMake(<#x#>, <#y#>, <#w#>, <#h#>)];
gifImageView.animationImages = frames; //将图片数组加入UIImageView动画数组中
gifImageView.animationDuration = 0.15; //每次动画时长
[gifImageView startAnimating]; //开启动画,此处没有调用播放次数接口,UIImageView默认播放次数为无限次,故这里不做处理
[self.view addSubview:gifImageView];

// 视频中获取图片 视频截取图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 正常mp4 好获取,不说 hls 渐进式加载, 理论我觉得seek 到位置 然后在获取 或者获取当前
CMTime itemTime = self.playerItem.currentTime;
CVPixelBufferRef pixelBuffer = [_playerItemVideoOutput copyPixelBufferForItemTime:itemTime itemTimeForDisplay:nil];
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
CIContext *temporaryContext = [CIContext contextWithOptions:nil];
CGImageRef videoImage = [temporaryContext
createCGImage:ciImage
fromRect:CGRectMake(0, 0,
CVPixelBufferGetWidth(pixelBuffer),
CVPixelBufferGetHeight(pixelBuffer))];
UIImage *uiImage = [UIImage imageWithCGImage:videoImage];
CGImageRelease(videoImage);
NSLog(@"uiImage:%@", uiImage);
self.myImgView.image = uiImage;
分析得到:copyPixelBufferForItemTime这个方法需要的参数是当前avplayerItem的cmtime, 也就是说前提是正在播放视频流,不知道有没有理解错。

视频播放时候如何在静音模式下有声音

1
2
3
4
5
6
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
//swift
let audioSession = AVAudioSession.sharedInstance()
try? audioSession.setCategory(AVAudioSessionCategoryPlayback);

// 简单保存视频到相册 —

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let filepath = GetDownFilePath(fileName).path
printLog("测试保存地址 \(filepath)")
if ( UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(filepath) == true){
UISaveVideoAtPathToSavedPhotosAlbum(filepath, self, #selector(self.video(videoPath:didFinishSavingWithError:contextInfo:)), nil);
}
func video(videoPath: String, didFinishSavingWithError error: NSError?, contextInfo info: AnyObject) {
}
////UIImageWriteToSavedPhotosAlbum 保存函数的通知处理函数
func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) {
if error == nil{
MBManage.shareMode.showBriefHUD("保存成功")
}else{
MBManage.shareMode.showBriefHUD("保存失败")
}
}

view 层级调整 ,互换 层最上层等

1
2
3
4
5
6
7
8
9
//将view1挪到最上边
self.view.bringSubviewToFront(view1)
//将view1挪到最下边
self.view.sendSubviewToBack(view1)
//互换
self.view.exchangeSubviewAtIndex(2, withSubviewAtIndex: 3)

swift 3 继承变量问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 父类
/// 基类 是否支持旋转 默认false 不旋转
open var isRotate:Bool = false
/// 子类
override var isRotate: Bool {
get{
// return super.isRotate // 可设置
return true// 直接改成需要的true
}
set{
super.isRotate = newValue
}
}

是否显示状态栏

1
2
3
4
5
//在info.plist中添加
//View controller-based status bar appearance
//并且把值设定为NO,就可以在程序中自由控制状态栏的隐藏和显示了。
UIApplication.shared.setStatusBarHidden(false, with: UIStatusBarAnimation.none)

navigationController 自带边缘右滑 退出, 代理 可以设置启用和不启用 UIGestureRecognizerDelegate

1
2
3
4
5
6
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
//代理
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}

iOS获取数组的最大值

1
2
3
4
5
6
7
NSMutableArray* array = [NSMutableArray array];
for (int i = 0; i < 10; i++) {
CGFloat num = arc4random() % 100 + 1;
[array addObject:[NSNumber numberWithFloat:num]];
}
CGFloat maxValue = [[array valueForKeyPath:@"@max.floatValue"] floatValue];
CGFloat minValue = [[array valueForKeyPath:@"@min.floatValue"] floatValue];

重点在这句话上
@”@max.floatValue”(获取最大值),
@”@min.floatValue”(获取最小值),
@”@avg.floatValue” (获取平均值),
@”@count.floatValue”(获取数组大小)
等等。。。。


oc通过强制类型转换四舍五入。swift 同理可行

1
2
3
4
float f = 1.5;
int a;
a = (int)(f+0.5);
NSLog("a = %d",a);

TabBarViewController 和UINavigationController的bar 上的黑线

1
2
3
let tabFrame = CGRect(x: 0, y: 0, width: stageWidth, height: self.tabBar.frame.height)
self.tabBar.backgroundImage = Getdevice.shared().image(withFrame: tabFrame, alphe: 1.0)
self.tabBar.shadowImage = UIImage()

UINavigationController 中的navigationBar 同理


iOS 字符串 中包含 % 百分号的方法

百分号的转换,NSString中需要格式化的字符串中百分号使用%%表示,而char*中百分号也是使用%%表示。

例如:NSLog(@”%%%@%%”,@”hello”),控制台会打印出%hello%。


cell 选择按钮替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/// 用户发布的视频显示 cell
class UserVideoManagerTableViewCell: UITableViewCell {
var showView:ShowVideoTableCellView!
override func layoutSubviews() {
super.layoutSubviews()
if #available(iOS 8 , *){
// ios7 没效果 第一次也不出现,还是得子定义
for control in self.subviews{
if control.isMember(of: NSClassFromString("UITableViewCellEditControl")!){
for v in control.subviews{
if v.isKind(of: UIImageView.classForCoder()){
//var img = v as! UIImageView
// v = UIImageView(image: UIImage(named: "activity_close"))
if self.isSelected{
(v as! UIImageView).image = UIImage(named: "v2_4_btn_set_selected")
}else{
//(v as! UIImageView).image = UIImage(named: "activity_new")//必须原先的图 因为效果不能一直有
}
}
}
}
}
}else{
for view in self.subviews{
if view.isMember(of: NSClassFromString("UITableViewCellScrollView")!){
printLog("views \(view.subviews)")
let views2 = view.subviews
for control in views2{
if control.isMember(of: NSClassFromString("UITableViewCellEditControl")!){
for v in control.subviews{
if v.isKind(of: UIImageView.classForCoder()){
let img = v as! UIImageView
if self.isSelected{
img.image = UIImage(named: "v2_4_btn_set_selected")
}else{
//img.image = UIImage(named: "activity_new")//必须原先的图 因为效果不能一直有
}
}
}
}
}
}
}
}
}
}

下面的方法本地还在
github 删除错误提交

git reset –hard HEAD~1
git push –force
就会删除远程的提交

1
2
3
git reset --hard <commit_id>
git push origin HEAD --force

其他:

1
2
3
4
5
6
7
8
9
10
11
根据–soft –mixed –hard,会对working tree和index和HEAD进行重置:
git reset –mixed:此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commitindex信息
git reset –soft:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可
git reset –hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容
HEAD 最近一个提交
HEAD^ 上一次
<commit_id> 每次commitSHA1值. 可以用git log 看到,也可以在页面上commit标签页里找到.
commit合并:

使用Cocoapods时忽略Xcode警告
我使用相当多的第三方库,其中有很多警告,在最新的Xcode更新后。 (例如Facebook SDK pod)
现在所有这些警告都显示在我的Xcode上我想看到自己的警告或错误的地方。
有没有办法忽略这些错误?修复它们不会有帮助,因为在每个“pod安装”之后,更改被丢弃。
添加到您的Podfile:

1
2
3
4
5
6
7
platform :ios
# ignore all warnings from all pods
inhibit_all_warnings!
# ignore warnings from a specific pod
pod 'FBSDKCoreKit', :inhibit_warnings => true

然后执行:pod install


链接
down vote
As it has already been answered, ObjC doesn’t support method overloading (two methods with the same name) and In swift 2 under Xcode 7 there are two options to solve this kind of problems. One option is to rename the method using the attribute: @objc(newNameMethod:)

func methodOne(par1, par2) {…}

@objc(methodTwo:) 标记为objc
func methodOne(par1) {…}
another option to solve this problem in Xcode 7+ is by applying @nonobjc attribute to any method, subscript or initialiser

func methodOne() {…}

@nonobjc // 标记为非objc
func methodOne() {…}


//NSRange转化为range
extension String {
func range(from nsRange: NSRange) -> Range? {
guard
let from16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location, limitedBy: utf16.endIndex),
let to16 = utf16.index(from16, offsetBy: nsRange.length, limitedBy: utf16.endIndex),
let from = String.Index(from16, within: self),
let to = String.Index(to16, within: self)
else { return nil }
return from ..< to
}
}

//range转换为NSRange
extension String {
func nsRange(from range: Range) -> NSRange {
let from = range.lowerBound.samePosition(in: utf16)
let to = range.upperBound.samePosition(in: utf16)
return NSRange(location: utf16.distance(from: utf16.startIndex, to: from),
length: utf16.distance(from: from, to: to))
}
}

swift 4

NSRange(range, in: string) //return 这个 range 转NSRange

/// string 中 查找子串
extension String {
func nsranges(of string: String) -> [NSRange] {
return ranges(of: string).map { (range) -> NSRange in
self.nsrange(fromRange: range)
}
}
}

// range 转 NSRange
extension String {
func nsrange(fromRange range : Range) -> NSRange {
return NSRange(range, in: self)
}
}

链接:
链1 链2


1
2
3
4
5
6
7
8
9
10
// kvc 实现提示 TextView 的提示文本(私有api)
self.placeHolderLabel = UILabel()
self.placeHolderLabel.font = GlobalFont_32
self.placeHolderLabel.textColor = UIColor.lightGray
self.placeHolderLabel.text = "请输入内容"
self.placeHolderLabel.sizeToFit()
self.inputeTextView.addSubview(self.placeHolderLabel)
self.inputeTextView.setValue(self.placeHolderLabel, forKey: "_placeholderLabel")
或者用titleTextField.attributedPlaceholder 参数

—YYlabel-YY–

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 一个yylabel 搞点点击处理
func setData(mode:MJ_UserMessage){
self.mode = mode
let titleString = "\(mode.source_title) 赞了你的视频"
let attrText = NSMutableAttributedString(string: titleString)
attrText.yy_font = GlobalFont_32
attrText.yy_color = GlobalMainToneTextColor_lime
let fromUserRange = NSMakeRange(0, mode.source_title.characters.count)
let fromUserHighlight = YYTextHighlight.init(backgroundColor: UIColor.clear)// 高亮的背景色 先没有
fromUserHighlight.userInfo = ["MJ_UserMessage":mode];// 把评论者信息存储到userinfo中
attrText.yy_setTextHighlight(fromUserHighlight, range: fromUserRange)
attrText.yy_setColor(UIColor(red:0.90, green:0.30, blue:0.25, alpha:1.00), range: fromUserRange)
self.messageNameLabel.attributedText = attrText
self.messageNameLabel.sizeToFit() //YYLabel
self.messageNameLabel.highlightTapAction = { [weak self](containerView:UIView ,text:NSAttributedString ,range:NSRange ,rect:CGRect) in
if let weakSelf = self{
let highlight:YYTextHighlight = containerView.value(forKeyPath: "_highlight") as! YYTextHighlight
let mode = highlight.userInfo?["MJ_UserMessage"] as? MJ_UserMessage
/// 代理吧数据传出去 (被评论人无user ImageUrl 字段)
if mode == nil || mode?.source_type != "user"{return}
DispatchQueue.main.async {
let controller = MyMainPageViewController(NavTitle: mode!.source_ID, userId: mode!.source_title)
weakSelf.findController().navigationController?.pushViewController(controller, animated: true)
}
}
}
}

ios 防止锁屏

1
UIApplication.shared.isIdleTimerDisabled = true // 长亮 反之正常

一个oc警告忽略
忽略 “Undeclared selector…” 的 Warning

1
2
3
4
if ([someObject respondsToSelector:@selector(someSelector)])
{
[someObject performSelector:@selector(someSelector)];
}

以上这句代码,除非你在 someObject 的头文件中显式地声明了 someSelector,否则在 Xcode 中会提示警告:
Undeclared selector ‘someSelector’
但很多情况下我们并不想去声明它,此时我们可以禁用编译器的此类警告:

1
#pragma GCC diagnostic ignored "-Wundeclared-selector"

这样将会在整个文件内禁用此类警告,也可只在部分代码处禁用,保证编译器依然会对文件内其他代码进行警告检测,避免出现预料之外的 bug:

1
2
3
4
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
// 需要禁用警告的代码
#pragma clang diagnostic pop

记录事件, GPUImage 运行时 崩溃 8.3 系统上 ,只有debug 连着电脑运行才崩溃 , 只要正常安装正常


Provisioning Profile相关
在~/Library/MobileDevice/Provisioning Profiles目录可以看到本机所有的Provisioning Profile,但是这里显示都是.mobileprovision这样的文件,并不是很好辨认。
一般更新设备删除~/Library/MobileDevice/Provisioning
在xcode 重新下载


ios 苹果的测试 The TestFlight app 中测试 可以测试正式环境的推送


xcode 代码块 导出到其他电脑使用
cd /Users/用户名/Library/Developer/Xcode/UserData/

将CodeSnippets拷贝到新电脑的对应的目录下


swift 4 字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
So, change
text.substring(to: 3)
text.substring(from: 3)
to
String(text.prefix(3))
String(text[text.index(text.startIndex, offsetBy: 3)...])
let newStr = str.substring(to: index) // Swift 3
let newStr = String(str[..<index]) // Swift 4
let newStr = str.substring(from: index) // Swift 3
let newStr = String(str[index...]) // Swift 4
let range = firstIndex..<secondIndex // If you have a range
let newStr = = str.substring(with: range) // Swift 3
let newStr = String(str[range]) // Swift 4

详情


根据字符串进行类的实例化 NSClassFromString 使用

1
2
3
4
5
6
7
//oc
Class vc_class = NSClassFromString(class_name);
//swift
let classtest = NSClassFromString("项目名.类名") as? 类名.Type
classtest?.init()
printLog("测试 \(classtest?.init())")

— 代码行数统计——
项目目录终端执行
其中 -name “*.m” 就表示扩展名为.m的文件。

1
find . "(" -name "*.m" -or -name "*.mm" -or -name "*.swift" -or -name "*.cpp" -or -name "*.h" -or -name "*.rss" ")" -print | xargs wc -l

swift KVO 需要的条件

swift 4 得 @objc dynamic
前缀 基于运行时,动态变量,
一般在swift 中用自动布局SDAutoLayout 自动cell 高度 需要使用这个


一个swift 闭包内存处理

1
2
3
4
5
6
7
8
9
lazy var newBtn: UIButton = {
// 可以直接self 因为lazy 自动处理了 (其他的一些 didSet 等 同理)
let obj = UIButton();
obj.addAction({ [weak self](btn) in
// 但是这里还是得标记
self?.delegate?.xxx
})
return obj;
}()


player 播放器网络差处理 摘取自CLPlayerDemo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#pragma mark - 监听
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"status"]) {
if (self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) {
self.state = CLPlayerStatePlaying;
self.player.muted = self.mute;
}
else if (self.player.currentItem.status == AVPlayerItemStatusFailed) {
self.state = CLPlayerStateFailed;
}
} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
// 计算缓冲进度
NSTimeInterval timeInterval = [self availableDuration];
CMTime duration = self.playerItem.duration;
CGFloat totalDuration = CMTimeGetSeconds(duration);
[self.maskView.progress setProgress:timeInterval / totalDuration animated:NO];
} else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
// 当缓冲是空的时候
if (self.playerItem.isPlaybackBufferEmpty) {
[self bufferingSomeSecond];
}
} else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
// 当缓冲好的时候
if (self.playerItem.isPlaybackLikelyToKeepUp && self.state == CLPlayerStateBuffering){
self.state = CLPlayerStatePlaying;
}
}
}
#pragma mark - 缓冲较差时候
//卡顿时会走这里
- (void)bufferingSomeSecond{
self.state = CLPlayerStateBuffering;
// 需要先暂停一小会之后再播放,否则网络状况不好的时候时间在走,声音播放不出来
[self pausePlay];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self playVideo];
// 如果执行了play还是没有播放则说明还没有缓存好,则再次缓存一段时间
if (!self.playerItem.isPlaybackLikelyToKeepUp) {
[self bufferingSomeSecond];
}
});
}

一个xcode注释文档警告忽略
Bulid Settings -> Documentation Comments -> NO


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
常用的一些占位符:
%@:字符串占位符
%d:整型
%ld:长整型
%f:浮点型
%c:char类型
%%:%的占位符
BOOL studyBool = YES;
NSLog(@"打印BOOL型数据%@",studyBool?@"YES":@"NO");//打印BOOL型数据YES
NSLog(@"打印BOOL型数据%d",studyBool);//打印BOOL型数据1
BOOL alsoBool = NO;
NSLog(@"打印BOOL型数据%@",alsoBool?@"YES":@"NO");//打印BOOL型数据NO
NSLog(@"打印BOOL型数据%d",alsoBool);//打印BOOL型数据0
详细介绍:**********************************************************
%@: Objective-C对象,印有字符串返回descriptionWithLocale:如果于的话,或描述相反.CFTypeRef工作对象,返回的结果的CFCopyDescription功能.(这个翻译有问题建议按照自己的理解方式理解)。
%%: 为'%'字符;
%d,%D,%i: 为32位整型数(int);
%u,%U: 为32位无符号整型数(unsigned int);
%hi: 为有符号的16位整型数(short);
%hu: 为无符号的16位整型数(unsigned shord);
%qi: 为有符号的64位整型数(long long);
%qu: 为无符号的64位整型数(unsigned long long);
%x: 为32位的无符号整型数(unsigned int),打印使用数字0-9的十六进制,小写a-f;
%X: 为32位的无符号整型数(unsigned int),打印使用数字0-9的十六进制,大写A-F;
%qx: 为无符号64位整数(unsigned long long),打印使用数字0-9的十六进制,小写a-f;
%qX: 为无符号64位整数(unsigned long long),打印使用数字0-9的十六进制,大写A-F;
%o,%O: 为32位的无符号整数(unsigned int),打印八进制数;
%f: 为64位的浮点数(double);
%e: 为64位的浮点数(double),打印使用小写字母e,科学计数法介绍了指数的增大而减小;
%E: 为64位的浮点数(double),打印科学符号使用一个大写E介绍指数的增大而减小;
%g: 为64位的浮点数(double),用%e的方式打印指数,如果指数小于4或者大于等于精度,那么%f的风格就会有不同体现;
%G: 为64位的浮点数(double),用%E的方式打印指数,如果指数小于4或者大于等于精度,那么%f的风格就会有不同体现;
%c: 为8位的无符号字符%c(unsigned char),通过打印NSLog()将其作为一个ASCII字符,或者,不是一个ASCII字符,八进制格式\ddd或统一标准的字符编码的十六进制格式\udddd,在这里d是一个数字;
%C: 为16位Unicode字符%C(unichar),通过打印NSLog()将其作为一个ASCII字符,或者,不是一个ASCII字符,八进制格式\ddd或统一标准的字符编码的十六进制格式\udddd,在这里d是一个数字;
%s: 对于无符号字符数组空终止,%s系统中解释其输入编码,而不是别的,如utf-8;
%S: 空终止一系列的16位Unicode字符;
%p: 空指针(无效*),打印十六进制的数字0-9和小写a-f,前缀为0x;
%L: 在明确规定的长度下,进行修正,下面的一批数据a,A,e,E,f,F,g,G应用于双精度长整型的参数;
%a: 为64位的浮点数(double),按照科学计数法打印采用0x和一个十六进制数字前使用小写小数点p来介绍指数的增大而减小;
%A: 为64位的浮点数(double),按照科学计数法打印采用0X和一个十六进制数字前使用大写字母小数点P界扫指数的增大而减小;
%F: 为64位的浮点数(double),按照十进制表示法进行打印;
%z: 修改说明在%z长度以下d,i,o,u,x,X适用于某一指定类型的转换或者适用于一定尺寸的整数类型的参数;
%t: 修改说明在%t长度以下d,i,o,u,x,X适用于某一指定类型或一定尺寸的整数类型的转换的参数;
%j: 修改说明在%j长度以下d,i,o,u,x,X适用于某一指定类型或一定尺寸的整数类型的转换的参数
Author

陈昭

Posted on

2017-03-01

Updated on

2021-12-27

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

Kommentare

You forgot to set the shortname for Disqus. Please set it in _config.yml.