<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[shiios的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/shiios</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; shiios]]></copyright><item><title><![CDATA[block循环引用]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/112885885</link><guid>https://blog.youkuaiyun.com/shiios/article/details/112885885</guid><author>shiios</author><pubDate>Wed, 20 Jan 2021 16:31:03 +0800</pubDate><description><![CDATA[typedef void(^GHBlock)(void);



底层源码

typedef void(*GHBlock)(void);

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  GHPerson *person;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, GHPerso]]></description><category></category></item><item><title><![CDATA[block的内存管理]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/112802063</link><guid>https://blog.youkuaiyun.com/shiios/article/details/112802063</guid><author>shiios</author><pubDate>Tue, 19 Jan 2021 11:33:52 +0800</pubDate><description><![CDATA[MRC环境下：
使用__block会使得底层将变量或者下面的person对象先包装成一个对象。

源码

typedef void(^GHBlock)(void);

__block GHPerson *person = [[GHPerson alloc]init];
        
        GHBlock block = ^{
          
            NSLog(@"%p",person);
            
        };
        
        ]]></description><category></category></item><item><title><![CDATA[block修改外部变量方式及底层原理]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/112778800</link><guid>https://blog.youkuaiyun.com/shiios/article/details/112778800</guid><author>shiios</author><pubDate>Mon, 18 Jan 2021 15:09:03 +0800</pubDate><description><![CDATA[方式一：

使用static修饰外部变量**NSGlobalBlock**
修改了变量类型，静态变量
会一直呆在内存中

 		typedef void(^GHBlock)(void);

		static int age = 10;
        GHBlock block = ^{
            age = 100;
            NSLog(@"age is %d",age);
            
        };
        block();
        NS]]></description><category></category></item><item><title><![CDATA[iOS 判断变量或者对象存储位置]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/112665532</link><guid>https://blog.youkuaiyun.com/shiios/article/details/112665532</guid><author>shiios</author><pubDate>Fri, 15 Jan 2021 14:25:57 +0800</pubDate><description><![CDATA[int age = 10;
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        int a = 100;
        
        NSLog(@"数据段：age %p",&amp;age); //数据段：age 0x100008208
        NSLog(@"栈：a %p",&amp;a); //栈：a 0x7ffeefbff41c
 ]]></description><category></category></item><item><title><![CDATA[block的几种类型（__NSGlobalBlock__，__NSStackBlock__，__NSMallocBlock__）]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/112648719</link><guid>https://blog.youkuaiyun.com/shiios/article/details/112648719</guid><author>shiios</author><pubDate>Fri, 15 Jan 2021 10:23:16 +0800</pubDate><description><![CDATA[void(^block)(void) = ^{

            NSLog(@"Hello");

        };

        NSLog(@"%@",[block class]); //__NSGlobalBlock__
        NSLog(@"%@",[[block class] superclass]); //NSBlock
        NSLog(@"%@",[[[block class] superclass] superclass]);//NSObject
  ]]></description><category></category></item><item><title><![CDATA[block变量捕获《一》]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/112621588</link><guid>https://blog.youkuaiyun.com/shiios/article/details/112621588</guid><author>shiios</author><pubDate>Thu, 14 Jan 2021 17:46:39 +0800</pubDate><description><![CDATA[代码如下，我们先看一个问题，这种情况下，变量会不会被block捕获。
#import &lt;Foundation/Foundation.h&gt;

NS_ASSUME_NONNULL_BEGIN

@interface GHPerson : NSObject

@property (nonatomic,copy) NSString *name;

- (void)test;

- (instancetype)initWithName:(NSString *)name;

@end

NS_ASSUME_]]></description><category></category></item><item><title><![CDATA[程序员可以通过什么方式赚钱？]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/111088713</link><guid>https://blog.youkuaiyun.com/shiios/article/details/111088713</guid><author>shiios</author><pubDate>Sun, 13 Dec 2020 10:11:11 +0800</pubDate><description><![CDATA[程序员的赚钱方式很多，这里我主要通过下面两个不同角色简单介绍一下:
上班族
上班族的工资结构主要分两个方面:
工资。这个工资自然就是公司发放的工资了。总包(部分公司会有总包25万，30万这种)也好加上年终奖(类似25*16)也好，都算是工资里面了。
副业。副业这种就和下面要说的自由职业者做的内容区别不大了。副业来源就丰富了，比如:写写公众号，写写博客，付费专栏，兼职讲师，程序员兼职平台接私单等等。
自由职业者
我身边就有朋友做自由职业者工作的，所谓自由职业者就是时间比较自由，可以每天睡到自然醒，也可以通宵.]]></description><category></category></item><item><title><![CDATA[iOS dealloc的底层调用实现]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/110876682</link><guid>https://blog.youkuaiyun.com/shiios/article/details/110876682</guid><author>shiios</author><pubDate>Tue, 08 Dec 2020 17:04:39 +0800</pubDate><description><![CDATA[#if LP64
static inline uint32_t ptr_hash(uint64_t key)
{
key ^= key &gt;&gt; 4;
key *= 0x8a970be7488fda55;
key ^= __builtin_bswap64(key);
return (uint32_t)key;
}
#else
static inline uint32_t ptr_hash(uint32_t key)
{
key ^= key &gt;&gt; 4;
key *= 0x5052acdb]]></description><category></category></item><item><title><![CDATA[苹果企业级开发者账号使用规范（同样适用于个人及公司级开发者账号）]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109899782</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109899782</guid><author>shiios</author><pubDate>Sat, 21 Nov 2020 16:07:47 +0800</pubDate><description><![CDATA[在我的iOS开发生涯中，曾做过这样几件事情：
分别申请成功过：
苹果个人开发者账号；
苹果公司级开发者账号；
苹果企业级开发者账号；
苹果商务管理分发账号（ABM，苹果后期将主推的一款账号，旨在替代企业级开发者账号）；
其中经历申诉账号的是苹果企业级开发者账号，做iOS开发的都应该明白，苹果企业级开发者账号意味着什么吧，而且这两年申请已经越发困难了，我去年申请的到现在还在审核中，由此可见，其申请难度是真的大。
我于去年遭遇公司的企业级开发者账号被锁定，14天申诉，这个在我以往的文章中有表述过，请查看：
《细]]></description><category></category></item><item><title><![CDATA[使用队列组解决任务执行顺序]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109362330</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109362330</guid><author>shiios</author><pubDate>Thu, 29 Oct 2020 16:07:45 +0800</pubDate><description><![CDATA[需求：
其他任务需要在任务1和任务2执行完成之后再进行执行。
//创建队列组
    dispatch_group_t group = dispatch_group_create();
    //创建并发队列
    dispatch_queue_t queue = dispatch_queue_create("my_queue", DISPATCH_QUEUE_CONCURRENT);
    
    //先执行任务一和任务2，然后执行完1和2后通知执行任务3（可以在主线程执行任务3）
    
  ]]></description><category></category></item><item><title><![CDATA[我们一起看一个多线程面试题一]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109359190</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109359190</guid><author>shiios</author><pubDate>Thu, 29 Oct 2020 14:39:43 +0800</pubDate><description><![CDATA[以上图中所示题目，要想打印   2   的话，则可以通过以下几种方法实现：
方式一：
添加运行循环：
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        
        NSLog(@"1");
        //下述代码本质是往runloop中添加定时器，因为是在block中执行，异步新建子线程默认不开启runloop，所以此处下面代码不会执行
    .]]></description><category></category></item><item><title><![CDATA[线程保活进化版]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109313669</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109313669</guid><author>shiios</author><pubDate>Tue, 27 Oct 2020 16:25:10 +0800</pubDate><description><![CDATA[A-&gt;B ，界面从A到B
在B中开启一个子线程：
//创建线程2
    self.stopped = NO;
    __weak typeof(self) wself = self;
    self.thread = [[GHThread alloc]initWithBlock:^{
        
        NSLog(@"%s--begin--%@",__func__,[NSThread currentThread]);
        
        [[NSRunLoop cu]]></description><category></category></item><item><title><![CDATA[线程保活《二》]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109308664</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109308664</guid><author>shiios</author><pubDate>Tue, 27 Oct 2020 12:51:59 +0800</pubDate><description><![CDATA[如若一个子线程开启是在一个view或者vc中，那么当vc或者view销毁后，那么其线程应该也随着销毁。
A-&gt;B  ，界面从A到B
在B中开启一个子线程：
//创建线程
    self.thread = [[GHThread alloc]initWithBlock:^{
        
        NSLog(@"%s--begin--%@",__func__,[NSThread currentThread]);
        
        [[NSRunLoop currentRunL]]></description><category></category></item><item><title><![CDATA[这样做线程的保活]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109303736</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109303736</guid><author>shiios</author><pubDate>Tue, 27 Oct 2020 09:17:28 +0800</pubDate><description><![CDATA[有时在工作中会遇到这种情况，我们开启了一个子线程，不希望它销毁，希望它可以一直存在，常驻后台或前台，但又不希望它一直工作，只有需要它的时候唤醒它，不需要它的时候让它休眠，这样当有问题要处理的时候，我们可以直接拿过来使用，不需要再重新开启新的子线程。
这里我们使用runloop来解决这个问题：
我们先创建一个类来监测线程是否被销毁：
.h
#import &lt;Foundation/Foundation.h&gt;

@interface MJThread : NSThread

@end

.m
#imp]]></description><category></category></item><item><title><![CDATA[runloop处理scrollview滚动时定时器失效的问题及runloop与timer的关系]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109292625</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109292625</guid><author>shiios</author><pubDate>Mon, 26 Oct 2020 16:36:26 +0800</pubDate><description><![CDATA[static int count = 0;
NSTimer *timer = [NSTimer timerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
        
     NSLog(@"%d",++count);
        
}];
    
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

由于NSTi.]]></description><category></category></item><item><title><![CDATA[runloop再探]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109292120</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109292120</guid><author>shiios</author><pubDate>Mon, 26 Oct 2020 16:26:20 +0800</pubDate><description><![CDATA[runloop运行逻辑


runloop休眠的实现原理：

用户操作的是应用层面api，然后反馈到底层的是内核层面的api。
有消息就唤醒发消息唤醒内核，处理用户操作反馈的消息，没有消息内核会让线程自动休眠。

...]]></description><category></category></item><item><title><![CDATA[Runloop初探笔记]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109291527</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109291527</guid><author>shiios</author><pubDate>Mon, 26 Oct 2020 16:10:42 +0800</pubDate><description><![CDATA[OC版runloop是C版CFRunLoopRef的封装：
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
        NSLog(@"%p----%p", [NSRunLoop currentRunLoop],[NSRunLoop mainRunLoop]);
        NSLog(@"%]]></description><category></category></item><item><title><![CDATA[我们一起看下如何做iOS性能优化]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109244794</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109244794</guid><author>shiios</author><pubDate>Fri, 23 Oct 2020 16:24:26 +0800</pubDate><description><![CDATA[性能优化的几个方面：
CPU优化：

GPU优化：


耗电优化：


启动优化：主要是针对冷启动的优化
添加环境变量，打印启动时间：DYLD_PRINT_STATISTICS
设置环境变量的值为1
详细启动时间：DYLD_PRINT_STATISTICS_DETAILS

安装包瘦身：

LinkMapGitHub仓库。

...]]></description><category></category></item><item><title><![CDATA[iOS  屏幕成像原理及页面卡顿原因]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109226141</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109226141</guid><author>shiios</author><pubDate>Thu, 22 Oct 2020 17:08:55 +0800</pubDate><description><![CDATA[]]></description><category></category></item><item><title><![CDATA[你应该知道如何判断一个指针是否是Tagged Pointer !]]></title><link>https://blog.youkuaiyun.com/shiios/article/details/109174618</link><guid>https://blog.youkuaiyun.com/shiios/article/details/109174618</guid><author>shiios</author><pubDate>Tue, 20 Oct 2020 09:35:57 +0800</pubDate><description><![CDATA[]]></description><category></category></item></channel></rss>