FLEX 学习笔记(一)

SystemLog 模块

该方式可以获取系统的log内容
PS:但是不知道为什么,该方式获取的log不完全是我们控制台输出的内容,求解?

NSArray* AMKSystemLogMessages() {
    asl_object_t query = asl_new(ASL_TYPE_QUERY);

    // Filter for messages from the current process. Note that this appears to happen by default on device, but is required in the simulator.
    NSString *pidString = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]];
    asl_set_query(query, ASL_KEY_PID, [pidString UTF8String], ASL_QUERY_OP_EQUAL);

    aslresponse response = asl_search(NULL, query);
    aslmsg aslMessage = NULL;

    NSMutableArray *systemLogMessages = [NSMutableArray array];
    while ((aslMessage = asl_next(response))) {
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];

        NSString *timestamp = [NSString stringWithCString:asl_get(aslMessage, ASL_KEY_TIME)?:"" encoding:NSUTF8StringEncoding];
        if (timestamp.length) {
            NSTimeInterval timeInterval = timestamp.integerValue;
            NSString *nanoseconds = [NSString stringWithCString:asl_get(aslMessage, ASL_KEY_TIME_NSEC)?:"" encoding:NSUTF8StringEncoding];
        if (nanoseconds.length) timeInterval += nanoseconds.doubleValue / NSEC_PER_SEC;
            dict[@"date"] = [NSDate dateWithTimeIntervalSince1970:timeInterval];
        }

        dict[@"sender"] = [NSString stringWithCString:asl_get(aslMessage, ASL_KEY_SENDER)?:"" encoding:NSUTF8StringEncoding];
        dict[@"text"] = [NSString stringWithCString:asl_get(aslMessage, ASL_KEY_MSG)?:"" encoding:NSUTF8StringEncoding];
        dict[@"ID"] = [NSString stringWithCString:asl_get(aslMessage, ASL_KEY_MSG_ID)?:"" encoding:NSUTF8StringEncoding];
        [systemLogMessages addObject:dict];
    }
    asl_release(response);

    return systemLogMessages;
}

Network 模块

字节数的转化为字符串

例子

long long bytes = 18237019123;
NSString *bytesText = [NSByteCountFormatter stringFromByteCount:bytes countStyle:NSByteCountFormatterCountStyleBinary];
NSLog(@"%@", bytesText);    //  输出: 16.98 GB

NSByteCountFormatter.h

/*  NSByteCountFormatter.h
Copyright (c) 2012-2015, Apple Inc. All rights reserved.
*/

#import <Foundation/NSFormatter.h>

NS_ASSUME_NONNULL_BEGIN

typedef NS_OPTIONS(NSUInteger, NSByteCountFormatterUnits) {
// This causes default units appropriate for the platform to be used. Specifying any units explicitly causes just those units to be used in showing the number.
NSByteCountFormatterUseDefault      = 0, 
//  Specifying any of the following causes the specified units to be used in showing the number.
NSByteCountFormatterUseBytes        = 1UL << 0, 
NSByteCountFormatterUseKB           = 1UL << 1,
NSByteCountFormatterUseMB           = 1UL << 2,
NSByteCountFormatterUseGB           = 1UL << 3, 
NSByteCountFormatterUseTB           = 1UL << 4, 
NSByteCountFormatterUsePB           = 1UL << 5, 
NSByteCountFormatterUseEB           = 1UL << 6, 
NSByteCountFormatterUseZB           = 1UL << 7, 
NSByteCountFormatterUseYBOrHigher   = 0x0FFUL << 8, 
// Can use any unit in showing the number.
NSByteCountFormatterUseAll          = 0x0FFFFUL 
};

typedef NS_ENUM(NSInteger, NSByteCountFormatterCountStyle) {
// Specifies display of file or storage byte counts. The actual behavior for this is platform-specific; on OS X 10.8, this uses the decimal style, but that may change over time.
NSByteCountFormatterCountStyleFile   = 0,        
// Specifies display of memory byte counts. The actual behavior for this is platform-specific; on OS X 10.8, this uses the binary style, but that may change over time.
NSByteCountFormatterCountStyleMemory = 1,
// The following two allow specifying the number of bytes for KB explicitly. It's better to use one of the above values in most cases.
NSByteCountFormatterCountStyleDecimal = 2,    // 1000 bytes are shown as 1 KB
NSByteCountFormatterCountStyleBinary  = 3     // 1024 bytes are shown as 1 KB
};


NS_CLASS_AVAILABLE(10_8, 6_0)
@interface NSByteCountFormatter : NSFormatter {
@private
unsigned int _allowedUnits;
char _countStyle;
BOOL _allowsNonnumericFormatting, _includesUnit, _includesCount, _includesActualByteCount, _adaptive, _zeroPadsFractionDigits;
int _formattingContext;
int _reserved[5];
}

/* Shortcut for converting a byte count into a string without creating an NSByteCountFormatter and an NSNumber. If you need to specify options other than countStyle, create an instance of NSByteCountFormatter first.
*/
+ (NSString *)stringFromByteCount:(long long)byteCount countStyle:(NSByteCountFormatterCountStyle)countStyle;

/* Convenience method on stringForObjectValue:. Convert a byte count into a string without creating an NSNumber.
*/
- (NSString *)stringFromByteCount:(long long)byteCount;

/* Specify the units that can be used in the output. If NSByteCountFormatterUseDefault, uses platform-appropriate settings; otherwise will only use the specified units. This is the default value. Note that ZB and YB cannot be covered by the range of possible values, but you can still choose to use these units to get fractional display ("0.0035 ZB" for instance).
*/
@property NSByteCountFormatterUnits allowedUnits;

/* Specify how the count is displayed by indicating the number of bytes to be used for kilobyte. The default setting is NSByteCountFormatterFileCount, which is the system specific value for file and storage sizes.
*/ 
@property NSByteCountFormatterCountStyle countStyle;

/* Choose whether to allow more natural display of some values, such as zero, where it may be displayed as "Zero KB," ignoring all other flags or options (with the exception of NSByteCountFormatterUseBytes, which would generate "Zero bytes"). The result is appropriate for standalone output. Default value is YES. Special handling of certain values such as zero is especially important in some languages, so it's highly recommended that this property be left in its default state.
*/
@property BOOL allowsNonnumericFormatting;

/* Choose whether to include the number or the units in the resulting formatted string. (For example, instead of 723 KB, returns "723" or "KB".) You can call the API twice to get both parts, separately. But note that putting them together yourself via string concatenation may be wrong for some locales; so use this functionality with care.  Both of these values are YES by default.  Setting both to NO will unsurprisingly result in an empty string.
*/
@property BOOL includesUnit;
@property BOOL includesCount;

/* Choose whether to parenthetically (localized as appropriate) display the actual number of bytes as well, for instance "723 KB (722,842 bytes)".  This will happen only if needed, that is, the first part is already not showing the exact byte count.  If includesUnit or includesCount are NO, then this setting has no effect.  Default value is NO.
*/
@property BOOL includesActualByteCount;

/* Choose the display style. The "adaptive" algorithm is platform specific and uses a different number of fraction digits based on the magnitude (in 10.8: 0 fraction digits for bytes and KB; 1 fraction digits for MB; 2 for GB and above). Otherwise the result always tries to show at least three significant digits, introducing fraction digits as necessary. Default is YES.
*/
@property (getter=isAdaptive) BOOL adaptive;

/* Choose whether to zero pad fraction digits so a consistent number of fraction digits are displayed, causing updating displays to remain more stable. For instance, if the adaptive algorithm is used, this option formats 1.19 and 1.2 GB as "1.19 GB" and "1.20 GB" respectively, while without the option the latter would be displayed as "1.2 GB". Default value is NO.
*/
@property BOOL zeroPadsFractionDigits;

/* Specify the formatting context for the formatted string. Default is NSFormattingContextUnknown.
*/
@property NSFormattingContext formattingContext NS_AVAILABLE(10_10, 8_0);

@end

NS_ASSUME_NONNULL_END

Data转JSONString

+ (NSString *)prettyJSONStringFromData:(NSData *)data {
    NSString *prettyString = nil;

    id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
    if ([NSJSONSerialization isValidJSONObject:jsonObject]) {
        prettyString = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:jsonObject options:NSJSONWritingPrettyPrinted error:NULL] encoding:NSUTF8StringEncoding];
        // NSJSONSerialization escapes forward slashes. We want pretty json, so run through and unescape the slashes.
        prettyString = [prettyString stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"];
    } else {
        prettyString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }

    return prettyString;
}

判断指定类的实例有没有实现某方法

+ (BOOL)instanceRespondsButDoesNotImplementSelector:(SEL)selector class:(Class)cls {
    if ([cls instancesRespondToSelector:selector]) {
        unsigned int numMethods = 0;
        Method *methods = class_copyMethodList(cls, &numMethods);

        BOOL implementsSelector = NO;
        for (int index = 0; index < numMethods; index++) {
            SEL methodSelector = method_getName(methods[index]);
            if (selector == methodSelector) {
                implementsSelector = YES;
                break;
            }
        }

        free(methods);

        if (!implementsSelector) {
            return YES;
        }
    }

    return NO;
}

objc_msgSend

用该语句可以实现消息的发送,即便是那些系统禁止手动调用的方法,如-dealloc;

((void(*)(id, SEL))objc_msgSend)(self, NSSelectorFromString(@"dealloc"));

FLEXUtility 模块

加载InfoPlist中配置的设备支持的方向值

+ (UIInterfaceOrientationMask)infoPlistSupportedInterfaceOrientationsMask {
    NSArray *supportedOrientations = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations"];
    UIInterfaceOrientationMask supportedOrientationsMask = 0;
    if ([supportedOrientations containsObject:@"UIInterfaceOrientationPortrait"]) {
        supportedOrientationsMask |= UIInterfaceOrientationMaskPortrait;
    }
    if ([supportedOrientations containsObject:@"UIInterfaceOrientationMaskLandscapeRight"]) {
        supportedOrientationsMask |= UIInterfaceOrientationMaskLandscapeRight;
    }
    if ([supportedOrientations containsObject:@"UIInterfaceOrientationMaskPortraitUpsideDown"]) {
        supportedOrientationsMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
    }
    if ([supportedOrientations containsObject:@"UIInterfaceOrientationLandscapeLeft"]) {
        supportedOrientationsMask |= UIInterfaceOrientationMaskLandscapeLeft;
    }
    return supportedOrientationsMask;
}

生成缩略图

/**
*  初始化并返回指定的数据图像的缩略图对象
*
*  @param data 包含图像数据的数据对象
*  @param size 生成的缩略图的最大宽高值
*
*  @return 返回一个初始化的UIImage对象,如果方法不能从指定的数据初始化图像则返回空
*/
+ (UIImage *)amk_thumbnailedImageWithData:(NSData *)data maxPixelSize:(CGFloat)size {
    UIImage *thumbnail = nil;
    CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, 0);
    if (imageSource) {
        NSDictionary *options = @{ (__bridge id)kCGImageSourceCreateThumbnailWithTransform : @YES,
                                   (__bridge id)kCGImageSourceCreateThumbnailFromImageAlways : @YES,
                                   (__bridge id)kCGImageSourceThumbnailMaxPixelSize : @(size) };

        CGImageRef scaledImageRef = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, (__bridge CFDictionaryRef)options);
        if (scaledImageRef) {
            thumbnail = [UIImage imageWithCGImage:scaledImageRef];
            CFRelease(scaledImageRef);
        }
        CFRelease(imageSource);
    }
    return thumbnail;
}

URL Query解析为字典

+ (NSDictionary *)dictionaryFromQuery:(NSString *)query {
    NSMutableDictionary *queryDictionary = [NSMutableDictionary dictionary];

    // [a=1, b=2, c=3]
    NSArray *queryComponents = [query componentsSeparatedByString:@"&"];
    for (NSString *keyValueString in queryComponents) {
    // [a, 1]
    NSArray *components = [keyValueString componentsSeparatedByString:@"="];
    if ([components count] == 2) {
        NSString *key = [[components firstObject] stringByRemovingPercentEncoding];
        id value = [[components lastObject] stringByRemovingPercentEncoding];

        // Handle multiple entries under the same key as an array
        id existingEntry = queryDictionary[key];
        if (existingEntry) {
            if ([existingEntry isKindOfClass:[NSArray class]]) {
                value = [existingEntry arrayByAddingObject:value];
            } else {
                value = @[existingEntry, value];
            }
        }

        [queryDictionary setObject:value forKey:key];
        }
    }

    return queryDictionary;
}

JSONString

+ (NSString *)prettyJSONStringFromData:(NSData *)data {
    NSString *prettyString = nil;

    id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
    if ([NSJSONSerialization isValidJSONObject:jsonObject]) {
        prettyString = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:jsonObject options:NSJSONWritingPrettyPrinted error:NULL] encoding:NSUTF8StringEncoding];
        // NSJSONSerialization escapes forward slashes. We want pretty json, so run through and unescape the slashes.
        prettyString = [prettyString stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"];
    } else {
        prettyString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }

    return prettyString;
}

数据解压

#import <zlib.h>

// Thanks to the following links for help with this method
// http://www.cocoanetics.com/2012/02/decompressing-files-into-memory/
// https://github.com/nicklockwood/GZIP
+ (NSData *)inflatedDataFromCompressedData:(NSData *)compressedData {
    NSData *inflatedData = nil;
    NSUInteger compressedDataLength = [compressedData length];
    if (compressedDataLength > 0) {
        z_stream stream;
        stream.zalloc = Z_NULL;
        stream.zfree = Z_NULL;
        stream.avail_in = (uInt)compressedDataLength;
        stream.next_in = (void *)[compressedData bytes];
        stream.total_out = 0;
        stream.avail_out = 0;

        NSMutableData *mutableData = [NSMutableData dataWithLength:compressedDataLength * 1.5];
        if (inflateInit2(&stream, 15 + 32) == Z_OK) {
        int status = Z_OK;
        while (status == Z_OK) {
            if (stream.total_out >= [mutableData length]) {
                mutableData.length += compressedDataLength / 2;
            }
            stream.next_out = (uint8_t *)[mutableData mutableBytes] + stream.total_out;
            stream.avail_out = (uInt)([mutableData length] - stream.total_out);
            status = inflate(&stream, Z_SYNC_FLUSH);
            }
            if (inflateEnd(&stream) == Z_OK) {
                if (status == Z_STREAM_END) {
                    mutableData.length = stream.total_out;
                    inflatedData = [mutableData copy];
                }
            }
        }
    }
    return inflatedData;
}

AllWindows

+ (NSArray *)allWindows {
    BOOL includeInternalWindows = YES;
    BOOL onlyVisibleWindows = NO;

    NSArray *allWindowsComponents = @[@"al", @"lWindo", @"wsIncl", @"udingInt", @"ernalWin", @"dows:o", @"nlyVisi", @"bleWin", @"dows:"];
    SEL allWindowsSelector = NSSelectorFromString([allWindowsComponents componentsJoinedByString:@""]);

    NSMethodSignature *methodSignature = [[UIWindow class] methodSignatureForSelector:allWindowsSelector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];

    invocation.target = [UIWindow class];
    invocation.selector = allWindowsSelector;
    [invocation setArgument:&includeInternalWindows atIndex:2];
    [invocation setArgument:&onlyVisibleWindows atIndex:3];
    [invocation invoke];

    __unsafe_unretained NSArray *windows = nil;
    [invocation getReturnValue:&windows];
    return windows;
}

判断实例响应并实现了指定方法

/**
*  判断实例响应并实现了指定方法
*
*  @author Andy__M, 2016/06/16 17:06
*  @param selector 方法名称
*  @return 若实例响应并实现了指定方法则返回YES,否则返回NO
*/
+ (BOOL)instanceRespondsButDoesNotImplementSelector:(SEL)selector class:(Class)cls {
    if ([cls instancesRespondToSelector:selector]) {
        unsigned int numMethods = 0;
        Method *methods = class_copyMethodList(cls, &numMethods);

        BOOL implementsSelector = NO;
        for (int index = 0; index < numMethods; index++) {
            SEL methodSelector = method_getName(methods[index]);
            if (selector == methodSelector) {
                implementsSelector = YES;
                break;
            }
        }

        free(methods);

        if (!implementsSelector) {
            return YES;
        }
    }

    return NO;
}

另类的拼串方式

#define FLEXEncodeClass(class) ("@\"" #class "\"")
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容