0%

pipe 函数

管道是一种两个进程间进行单向通信的机制;因为管道传递数据的单向性,管道又称为半双工管道。

Linux 进程间通讯方式:

  1. 管道(pipe)和有名管道(fifo)
  2. 消息队列
  3. 共享内存
  4. 信号量
  5. 信号(signal)
  6. 套接字(sicket)

头文件

1
#include <unistd.h>

函数原型

1
int pipe(int fd[2]);

返回值:

1
2
1.  0,成功。
2. -1,失败。
阅读全文 »

fork 函数

一个进程,包括代码、数据以及所分配的资源。fork() 函数通过系统的调用创建一个与原来进程几乎完全相同的新进程,可以做完全相同的事;但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。

一个进程调用 fork() 函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

头文件

1
#include <unistd.h>

函数原型

1
pid_t fork(void);

返回值

1
2
3
1. -1, 创建失败。
2. 0, 创建成功,返回子进程。
3. >0, 创建成功,返回子进程 ID 给父进程。

功能

阅读全文 »

WAVE 文件

WAVE 文件格式是微软用来存储多媒体文件的一个子集;遵循 RIFF资源交换档案格式

一个 RIFF 文件从一个文件头开始,然后是一个数据块的序列。WAVE文件通常只是一个重复的文件,其中包含一个WAVE块,它由两个子块组成——一个fmt块指定数据格式和一个包含实际示例数据的data块。

标准的 WAVE 文件格式(图片来源于这里

wav-sound-format.gif

其文件头结构体如下:

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
typedef unsigned int uInt32;
typedef unsigned short uInt16;

// 除说明外,其他都是 小端模式
typedef struct __RIFF {
char riffChunkID[4]; // 固定标识 'RIFF' (大端模式)
uInt32 fileSize; // 文件大小(除掉标志'RIFF' + 这个整数本身)
char format[4]; // 固定标识 'WAVE' (大端模式)
}RIFF;


typedef struct __FMT {
char fmtChunkID[4]; // 固定标识 'fmt ' (大端模式)
uInt32 fmtChunkSize; // fmt 区块大小(除掉标志'fmt ' + 这个整数本身)
uInt16 audioFormat; // 格式类型(pcm = 1)
uInt16 numChannels; // 声道数(Mono = 1, Stereo = 2)
uInt32 sampleRate; // 采样率(48000, 44100)
uInt32 byteRate; // 每秒播放字节数(码率/8) = sampleRate * numChannels * bitsPerSample/8
uInt16 blockAlign; // DATA数据块单位(单位采样)长度 = numChannels * bitsPerSample/8
uInt16 bitsPerSample; // PCM位深 - 用来存储采样点y值所使用的二进制位个数(8 bits, 16 bits, 24 bits)
}FMTChunk;


typedef struct __DATA {
char dataChunkID[4]; // 固定标识'data'(大端模式)
uInt32 dataChunkSize; // 数据部分总长度 区块大小(除掉标志'data' + 这个整数本身)
}DATAChunk;


typedef struct __WAVE {
RIFF riff; // riff 块
FMTChunk fmt; // fmt 块
DATAChunk data; // data 块
}WAVHead;

OpenAL

OpenAL(Open Audio Library)是自由软件界的跨平台音效API。它设计给多通道三维位置音效的特效表现。其API风格模仿自 OpenGL

API 结构和功能

  1. OpenAL 主要的功能是在来源物体音效缓冲收听者中编码。
    • 来源物体:包含一个指向缓冲器的指针、声音的速度、位置和方向,以及声音强度。
    • 音效缓冲:包含8或16位、单声道或立体声 PCM 格式的音效数据,表现引擎进行所有必要的计算,如距离衰减、多普勒效应等。
    • 收听者:包含收听者的速度、位置和方向,以及全部声音的整体增益。
  2. 不同于OpenGL规格,OpenAL规格包含两个API分支:
    • 以实际 OpenAL 函数组成的核心。
    • ALC:用于管理表现内容、资源使用情况,并将跨平台风格封在其中。还有ALUT程序库,提供高级“易用”的函数,其定位相当于OpenGL的GLUT。
阅读全文 »

  1. 在对 iOS APP 开发时,不可避免需要对 APP 进行多语言化,特别是做 ODM 的开发,更需要实现 APP 国际化。
  2. 当订单不断的来时,意味着需要不断地适配多语言化;此时就需要先把工程代码里面已有的 Localizable.strings 导出到 xls 文档,然后再给相应的翻译部门或者外包翻译公司进行翻译。遗憾的是 Xcode 没有提供便捷地把 Localizable.strings 导出到 xlscsv 的功能(或者有而我并没有发现。)最后,这一简单而又非常繁琐的工作就落在了 Comm+CComm+V 身上了;如果是一百几十个还好,但如果是成千上万的,那是得多大的工作量啊,宝贵的时间就这样白白浪费了,而且还不能保证复制、粘贴过程中不会出错。
  3. 接了几次多语言化适配的我,已经疲惫不堪,下定决心做个简单的解释器出来,来缓解工作量,同时节省时间成本。于是乎,SYStringsParser 就诞生了,欢迎大家下载体验。。

Parsr strings

Parsr csv

功能

  1. 便捷地把多个 Localizable.strings 文件合并转为一个 csv文件。

  2. 同时支持把 csv 转化为多个 Localizable.strings 文件。

  3. 同时支持去重,保证对同一 key 的翻译唯一性。

dmg下载

阅读全文 »

在做视图展示是,为了保留原视图(如:视频、图片等)的比例不被改变,就必需把原始图进行 等比例缩放,以更好的展示。可以分为 4 种情况:

  1. 横屏展示横屏视图:

  2. 竖屏展示竖屏视图:

  3. 横屏展示竖屏视图:

  4. 竖屏展示横屏视图:

代码

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
/**
等比例缩放子视图以适应父视图展示

@param subSize 子视图原始 size
@param parentSize 父视图原始 size
@return 等比例缩放后 frame
*/
+ (CGRect)scaleWithSubSize:(CGSize)subSize
inParentSize:(CGSize)parentSize
{
CGRect resultRect = CGRectMake(0, 0, 0, 0);

if (0 == subSize.width || 0 == subSize.height)
{
return resultRect;
}
CGFloat subDivisor = parentSize.width / parentSize.height; // 子视图比例因子(宽/高)
CGFloat parentDivisor = subSize.width / subSize.height; // 父视图比例因子(宽/高)

CGFloat resultH;
CGFloat resultW;
CGPoint originP;

if (subDivisor > parentDivisor ) // 等高缩放
{
resultH = parentSize.height;
resultW = resultH * parentDivisor;
}
else if ( subDivisor < parentDivisor) // 等宽缩放
{
resultW = parentSize.width;
resultH = resultW / parentDivisor;
}

else // 等比例缩放
{
resultW = parentSize.width;
resultH = parentSize.height;
}
// 起点位置
originP.x = (parentSize.width - resultW) / 2.0f;
originP.y = (parentSize.height - resultH) / 2.0f; ;
resultRect = CGRectMake(originP.x, originP.y, resultW, resultH);

return resultRect;
}

效果

Demo 下载

阅读全文 »

记录 iOS 常用代码片段。

判断当前网络状态 Demo

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
53
54
55
56
57
58
59
60
61
62
63
64
/** 网络状态枚举 */
typedef NS_ENUM(NSUInteger, SYNetworkState) {
SYNetwork_Unknow = 0x00, // 未知
SYNetwork_No = 0x01, // 无网络
SYNetwork_2G = 0x02, // 2G 网络
SYNetwork_3G = 0x03, // 3G 网络
SYNetwork_4G = 0x04, // 4G 网络
SYNetwork_WiFi = 0x05, // WiFi 网络
};


#pragma mark -- 判断网络状态
+ (SYNetworkState)syNetworkState
{
UIApplication *application = [UIApplication sharedApplication];
NSArray *subViewArray;
// iPhone X
if ([[application valueForKeyPath:@"_statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")])
{
subViewArray = [[[[application valueForKeyPath:@"_statusBar"] valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
}
else // 其他
{
subViewArray = [[[application valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
}

int netType = 0;
SYNetworkState netState = SYNetwork_Unknow;
for (id subView in subViewArray)
{
if (![subView isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")])
{
continue;
}
netType = [[subView valueForKeyPath:@"dataNetworkType"] intValue];
}
switch (netType)
{
case 0:
netState = SYNetwork_No;
break;

case 1:
netState = SYNetwork_2G;
break;

case 2:
netState = SYNetwork_3G;
break;

case 3:
netState = SYNetwork_4G;
break;

case 5:
netState = SYNetwork_WiFi;
break;

default:
netState = SYNetwork_Unknow;
break;
}
return netState;
}

屏幕亮度渐变 Demo

  1. didFinishLaunchingWithOptions: 保存默认亮度值。

    1
    2
    3
    [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO]
    forKey:IS_NEED_CHANGE_BRIGHTNESS];
    [GradualBrightness sySaveDefaultBrightness];
  2. applicationWillResignActive: 恢复默认亮度值(如果需要)。

    1
    2
    3
    4
    5
    6
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    BOOL isNeedChangeBrightness = [[userDefault objectForKey:IS_NEED_CHANGE_BRIGHTNESS] boolValue];
    if (YES == isNeedChangeBrightness)
    {
    [GradualBrightness syResumeBrightness];
    }
  3. applicationDidBecomeActive: 设定新亮度值(如果需要)。

    1
    2
    3
    4
    5
    6
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    BOOL isNeedChangeBrightness = [[userDefault objectForKey:IS_NEED_CHANGE_BRIGHTNESS] boolValue];
    if (YES == isNeedChangeBrightness)
    {
    [GradualBrightness syConfigBrightness:CUSTOM_BRIGHTNESS_VAULE];
    }
  4. viewWillAppear: 设定新亮度值(同时设为需要)。

    1
    2
    3
    [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES]
    forKey:IS_NEED_CHANGE_BRIGHTNESS];
    [GradualBrightness syConfigBrightness:CUSTOM_BRIGHTNESS_VAULE];
  5. viewWillDisappear: 恢复默认亮度值(同时设为不需要)。

    1
    2
    3
    [GradualBrightness syResumeBrightness];
    [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO]
    forKey:IS_NEED_CHANGE_BRIGHTNESS];
  6. 实现代码

    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
    /** 亮度变换步幅 */
    #define GRADUAL_STRIDE 0.005f

    static CGFloat defaultBrightness;
    static NSOperationQueue *changeBrightnessQueue;


    #pragma mark -- 保存默认亮度值
    + (void)sySaveDefaultBrightness
    {
    defaultBrightness = [UIScreen mainScreen].brightness;
    }


    #pragma mark -- 逐步设置亮度
    + (void)syConfigBrightness:(CGFloat)value
    {
    if (!changeBrightnessQueue)
    {
    changeBrightnessQueue = [[NSOperationQueue alloc] init];
    changeBrightnessQueue.maxConcurrentOperationCount = 1;
    }
    [changeBrightnessQueue cancelAllOperations];

    CGFloat brightness = [UIScreen mainScreen].brightness;
    CGFloat stride = GRADUAL_STRIDE * ((value > brightness) ? 1 : -1);
    NSInteger times = fabs((value - brightness) / GRADUAL_STRIDE);
    for (NSInteger i = 1; i <= times; i++)
    {
    [changeBrightnessQueue addOperationWithBlock:^{

    [NSThread sleepForTimeInterval:1 / 180.0];
    [UIScreen mainScreen].brightness = brightness + i * stride;
    }];
    }
    }


    #pragma mark -- 逐步恢复亮度
    + (void)syResumeBrightness
    {
    [self syConfigBrightness:defaultBrightness];
    }
阅读全文 »

SYDeviceInfo

获取 iOS 设备信息。

iPhone 5S 信息

iPhone 5S 信息

模拟器 iPhone 7 信息

模拟器 iPhone 7 信息

获取当前设备的’名称’

1
2
3
4
5
6
/**
获取当前设备的'名称',参见'SYNameType'

@return 具体的设备类型, 参见‘DeviceType’
*/
+ (SYNameType)syDeviceName;

获取当前设备的‘类型’

1
2
3
4
5
6
/**
获取当前设备的‘类型’,参见'SYDeviceType'

@return 设备类型,参见‘SYDeviceType’
*/
+ (SYDeviceType)syDeviceType;
阅读全文 »

冒泡排序

冒泡排序(Bubble Sort)是所有排序算法中最简单的、最基本的一种;其思路就是交换排序,通过相邻数据的交换来达到排序的目的。

  1. 时间复杂度:平均时间复杂度为:O(n * n),最差时间复杂度为:O(n * n)
  2. 空间复杂度:O(1)

执行流程:

  1. 对数组中的各数据,依次比较相邻的两个元素的大小。
  2. 如果前面的数据大于(小于)后面的数据,就交换这两个数据。经过第一轮的多次比较排序后,便可把最小(大)的数据排好。
  3. 然后,再用相同的方法把剩下的数据逐个进行比较,最后便可按照从小到大(从大到小)的顺序排好数组中各数据的顺序。

示例

排序原始数据:39 52 89 44 86 26

升序排序(从小到大):

冒泡排序

排序后结果:26 39 44 52 86 89

阅读全文 »

概率算法思想

概率算法(Probability)依照概率统计的思路来求解问题;但往往不能得到问题的精确解,却是通过数值计算来求解近似值。

执行过程

  1. 将问题转化为相应的几何图形 SS的面积是容易计算的,问题的结果往往对应几何图形中某一部分 S1的面积。
  2. 然后,向几何图形中随机撒点。
  3. 统计几何图形 SS1 的点数。根据 S 的面积和 S1 面积的关系以及各图形中的点数来计算得到结果。
  4. 判断上述结果是否在需要的精度之内,如果未达到精度则执行步骤 2;如果达到精度则输出近似值。

算法的形式

  1. 数值概率算法。
  2. 蒙特卡罗(Monte Carlo)算法。
  3. 拉斯维加斯(Las Vegas)算法。
  4. 舍伍德(Sherwood)算法。

示例

蒙特卡罗(Monte Carlo)—— π 算法

蒙特卡罗π算法思想

  1. 如上图,设一个半径为 1 的圆,其面积为:S = π * r * r = π,(r == 1)
  2. 图中阴影部分是圆的 1/4,其面积为:S1 = S / 4 = π / 4
  3. 图中正方形的面积为:S2 = r * r = 1
阅读全文 »

分治算法思想

分治算法(Divide and Conquer)是一种化繁为简的算法思想;其基本思想就是将一个计算复杂的问题分为规模较小,计算简单的小问题求解,然后综合各个小问题,得到最终问题的答案。

执行过程

  1. 对于一个规模为 N 的问题,若该问题可以容易地解决(比如说规模 N 较小),则直接解决;否则执行下面的步骤。
  2. 将该问题分解为 M 个规模较小的子问题,这些子问题相互独立,并且与原问题形式相同。
  3. 递归地解子问题。
  4. 然后,将各个子问题的解合并得到原问题的解。

注意:使用分治算法需要待求解问题能够化简为若干个小规模的相同问题,通过逐步划分,达到一个易于求解的阶段而直接进行求解;然后,程序中可以使用递归算法来进行求解。

示例

假币问题

题意:一个袋子里有 N 个硬币,其中有一枚是假币,并且假币和真币外观一模一样,肉眼无法区分;目前只知道假币比真币重量轻一点;问,如何找出假币?

解析:

  1. 将所有的硬币等分成两份,放在天平的两边。这样就将区分 N 个硬币的问题,简化为区分两堆硬币的问题。
  2. 由题意可知,天平较轻的一侧必定包含有假币在其中。
  3. 再将较轻的一侧中的硬币等分成两份,重复上述步骤。
  4. 直到剩下 2枚硬币,可用天平直接找出假硬币。
阅读全文 »