文章目录
  1. 1. 问题杂烩
    1. 1.1. 判断字符串是不是纯数字
    2. 1.2. Attempt to present XX on XX whose view is not in the window hierarchy
    3. 1.3. 指定颜色生成图片
    4. 1.4. 获取系统版本、型号等信息
    5. 1.5. 读写plist文件
    6. 1.6. XCode快捷键
    7. 1.7. pragma使用
      1. 1.7.1. 组织代码
      2. 1.7.2. 屏蔽警告
      3. 1.7.3. 其他方式
    8. 1.8. 图片旋转问题
    9. 1.9. 判断用户短时间内发送消息太多
      1. 1.9.1. 另外一种方式

问题杂烩

判断字符串是不是纯数字

/// 判断字符串是不是纯数字
- (BOOL)isPureNumandCharacters:(NSString *)string
{
string = [string stringByTrimmingCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]];
if(string.length > 0)
{
return NO;
}
return YES;
}

Attempt to present XX on XX whose view is not in the window hierarchy

Attempt to present <LoginVC: 0x9358770> on <ViewController: 0x9529380> whose view is not in the window hierarchy
  • 也就是你在呈现一个LoginVC时,但ViewController的view并不在window上,可能是因为ViewController还没被显示出来。

  • 所以不要在某个viewController的viewDidLoad或者viewWillAppear方法中去呈现其他的viewController,你如果想要的是ViewController显示之后马上呈现LoginVC的话,可以在viewDidAppear中写方法。

指定颜色生成图片

//指定颜色生成图片:
+ (UIImage *)imageWithColor:(UIColor *)color
{
CGRect rect = CGRectMake(0, 0, 1, 1);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return image;
}

获取系统版本、型号等信息

  • 获取基本信息
//  IOS-获取Model(设备型号)、Version(设备版本号)、app(程序版本号)等  
NSLog(@"name: %@", [[UIDevice currentDevice] name]);
NSLog(@"systemName: %@", [[UIDevice currentDevice] systemName]);
NSLog(@"systemVersion: %@", [[UIDevice currentDevice] systemVersion]);
NSLog(@"model: %@", [[UIDevice currentDevice] model]);
NSLog(@"localizedModel: %@", [[UIDevice currentDevice] localizedModel]);



NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];

CFShow((__bridge CFTypeRef)(infoDictionary));

// app名称
NSString *app_Name = [infoDictionary objectForKey:@"CFBundleDisplayName"];
// app版本
NSString *app_Version = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
// app build版本
NSString *app_build = [infoDictionary objectForKey:@"CFBundleVersion”];
  • 获取具体型号,如5s,6P等
#import "sys/utsname.h"


//获得设备型号
+ (NSString *)getCurrentDeviceModel
{
struct utsname systemInfo;
uname(&systemInfo);
NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];

if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G (A1203)";
if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G (A1241/A1324)";
if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS (A1303/A1325)";
if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4 (A1332)";
if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4 (A1332)";
if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4 (A1349)";
if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S (A1387/A1431)";
if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5 (A1428)";
if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (A1429/A1442)";
if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (A1456/A1532)";
if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (A1507/A1516/A1526/A1529)";
if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (A1453/A1533)";
if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (A1457/A1518/A1528/A1530)";
if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus (A1522/A1524)";
if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6 (A1549/A1586)";

if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G (A1213)";
if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G (A1288)";
if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G (A1318)";
if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G (A1367)";
if ([platform isEqualToString:@"iPod5,1"]) return @"iPod Touch 5G (A1421/A1509)";

if ([platform isEqualToString:@"iPad1,1"]) return @"iPad 1G (A1219/A1337)";

if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2 (A1395)";
if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2 (A1396)";
if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2 (A1397)";
if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2 (A1395+New Chip)";
if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini 1G (A1432)";
if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini 1G (A1454)";
if ([platform isEqualToString:@"iPad2,7"]) return @"iPad Mini 1G (A1455)";

if ([platform isEqualToString:@"iPad3,1"]) return @"iPad 3 (A1416)";
if ([platform isEqualToString:@"iPad3,2"]) return @"iPad 3 (A1403)";
if ([platform isEqualToString:@"iPad3,3"]) return @"iPad 3 (A1430)";
if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4 (A1458)";
if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4 (A1459)";
if ([platform isEqualToString:@"iPad3,6"]) return @"iPad 4 (A1460)";

if ([platform isEqualToString:@"iPad4,1"]) return @"iPad Air (A1474)";
if ([platform isEqualToString:@"iPad4,2"]) return @"iPad Air (A1475)";
if ([platform isEqualToString:@"iPad4,3"]) return @"iPad Air (A1476)";
if ([platform isEqualToString:@"iPad4,4"]) return @"iPad Mini 2G (A1489)";
if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini 2G (A1490)";
if ([platform isEqualToString:@"iPad4,6"]) return @"iPad Mini 2G (A1491)";

if ([platform isEqualToString:@"i386"]) return @"iPhone Simulator";
if ([platform isEqualToString:@"x86_64"]) return @"iPhone Simulator";
return platform;
}

读写plist文件

  • 问题,我有一个plist文件,表示56个民族的,但是里面保存的字典,我想转换成一个数组
  • 好的,那么就先遍历这个plist,然后将结果保存到一个数组中,这里出现的一个问题就是C语言字符串转换成NSString的问题,一开始使用- (nullable id)initWithCString:(const char *)bytes,一直出问题,转换后有问题。
  • 然后我就换了一个方法- (nullable id)initWithCString:(const char *)bytes length:(NSUInteger)length 这个方法转换后没有问题了。
  • 第一个plist是按照26个英文字母为key的字典。
  • 结果,按照数组保存。
// 读取56个民族
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"nation.plist" ofType:nil];
NSDictionary *dict2 = [NSDictionary dictionaryWithContentsOfFile:filePath];

// 拼接路径
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES);
NSString *plistPath1 = [paths objectAtIndex:0];
NSString *filename = [plistPath1 stringByAppendingPathComponent:@"nation2.plist"];

NSMutableArray *mutab = [NSMutableArray array];

for (int i = 0 ; i < 26; i ++) {
char x = 65 + i;
NSString *str= [[NSString alloc] initWithCString:&x length:1];
NSArray *arr = dict2[str];
for (NSInteger j = 0; j < arr.count; j ++) {
[mutab addObject:arr[j]];
}
}
// 保存成数组
[mutab writeToFile:filename atomically:NO];
NSLog(@"%@",mutab);

XCode快捷键

command + option +J 快速定位到当前打开的类所在位置目录结构
command + 1…..7 切换工程选项卡左边的那个
ESC 代码自动补全
command + shift +k clean 工程
command + k 清空console 输出
command + f 搜索当前文件
command + shift + f 搜索整个工程
command + l 跳转到某一行
command + control + 左右方向键 前进或者后退已打开过的文件
command + control + 上下方向键 切换.h 和 .m文件
command + 0 隐藏/显示导航栏

pragma使用

组织代码

  • 组织N个方法为一个section的依据是什么呢?这个就见仁见智了。一般来说:
    • 将一个protocol的方法组织成一个section;
    • 将target-action类型方法组织成一个section;
    • 将notification相关方法组织成一个section;
    • 将需要override的父类方法组成成一个section;

屏蔽警告

#pragma clang diagnostic push
#pragma clang diagnostic i![](屏蔽编译警告.png)gnored "-Wundeclared-selector"
if ([self.selectedViewController respondsToSelector:@selector(isReadyForEditing)]) {
boolNumber = [self.selectedViewController performSelector:@selector(isReadyForEditing)];
}
#pragma clang diagnostic pop

其他方式

  • 某些时候如果我们的源码在编译过程中出现大量的编译警告时,看起来是挺不爽的;但又确实没办法解决警告问题的时候,我们可以使用下面的方法来屏蔽指定的某个文件的所有警告信息。
    • 1、在Xcode中选中工程文件。
    • 2、在右边面板中选中“Build Phases”。
    • 3、展开“Compile Sources”
    • 4、在需要屏蔽警告的源文件一行中双击“Compiler F lags”。
    • 5、在弹出窗口中输入-w

图片旋转问题

- (UIImage *)fixOrientation {

// No-op if the orientation is already correct
if (self.imageOrientation == UIImageOrientationUp) return self;

// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;

switch (self.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;

case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;

case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}

switch (self.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;

case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}

// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform);
switch (self.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
break;

default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
break;
}

// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}

判断用户短时间内发送消息太多

  • 看到这个问题时,我想到了定时器,首先定义一个变量numberOfSend保存发送次数,然后在第一次输入时开启定时器timer1,5s之内如果numberOfSend没有超过8条,就在5s后重置numberOfSend,如果5s内发送次数超过8条,就开启另一个定时器timer2,来延迟执行发送操作,在timer2中要先取消之前的timer1,然后就return

NSInteger _numberOfSendMessagesInFiveSecond;


- (void)sendMessages
{
_numberOfSendMessagesInFiveSecond = 0;
}

- (void)sendText:(NSString *)contentString
{
// 喝杯茶休息一下吧!
_numberOfSendMessagesInFiveSecond ++ ;
if ( 1 == _numberOfSendMessagesInFiveSecond){

[self performSelector:@selector(sendMessages) withObject:nil afterDelay:5];
}
else if (_numberOfSendMessagesInFiveSecond >= 9) {

[chatInputView insertTextAfterCursor:contentString];
[self presentSuccessTips:NSLocalizedString(@"CHATPANEL_TAKE_A_CUP_OF_TEA" ,@"喝杯茶休息一下吧!")];

if(_numberOfSendMessagesInFiveSecond == 9) {
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(sendMessages) object:nil];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_numberOfSendMessagesInFiveSecond = 0;
});
}
return;
}
}

另外一种方式

@interface P2PSendMsgFrequencyStrategy ()
{
NSInteger _iMaxCount;
long long _iMaxMillisecond; //1秒
NSInteger _iCount;
NSTimeInterval _lastSendTime;
}

@end

@implementation P2PSendMsgFrequencyStrategy

- (instancetype)init
{
self = [super init];
if (self)
{
_iMaxCount = 8;
_iMaxMillisecond = 1*1000; //1秒
_iCount = 0;
_lastSendTime = 0;
}
return self;
}

- (BOOL)sendMessageTooOften
{//规则是:5秒内发送超过8条就不能发送,然后再过5秒才能发送。
NSTimeInterval nowSendTime = [[NSDate date]timeIntervalSince1970]*1000;

long long time = (nowSendTime - _lastSendTime);
if ((time > _iMaxMillisecond*5 && _iCount < _iMaxCount)
|| (time > _iMaxMillisecond*10 && _iCount >= _iMaxCount)
)
{
_lastSendTime = [[NSDate date]timeIntervalSince1970]*1000;
_iCount = 0;

YJLog(@"sendMessage time:%lld", time);
return NO;
}
else
{
if (++_iCount < _iMaxCount)
{
YJLog(@"sendMessage count: %ld, time:%lld", (long)_iCount, time);
return NO;
}

}

YJLog(@"sendMessage Too Many: %ld, time:%lld", (long)_iCount, time);
return YES;
}

@end
文章目录
  1. 1. 问题杂烩
    1. 1.1. 判断字符串是不是纯数字
    2. 1.2. Attempt to present XX on XX whose view is not in the window hierarchy
    3. 1.3. 指定颜色生成图片
    4. 1.4. 获取系统版本、型号等信息
    5. 1.5. 读写plist文件
    6. 1.6. XCode快捷键
    7. 1.7. pragma使用
      1. 1.7.1. 组织代码
      2. 1.7.2. 屏蔽警告
      3. 1.7.3. 其他方式
    8. 1.8. 图片旋转问题
    9. 1.9. 判断用户短时间内发送消息太多
      1. 1.9.1. 另外一种方式