Git Product home page Git Product logo

Comments (20)

fangYaLei110 avatar fangYaLei110 commented on May 28, 2024 1

主要是没有想到 target 被释放的原因,可能是在 retainArguments 方法调用前其他线程写操作导致 target 释放,但我没复现这种 case;我最担心的是 invocation 被释放导致 target 进而被释放,这意味着只针对 target 判空保护是不够的,参数列表也危险了。不过在这个场景下我看都是在主线程(rule.messageQueue)上执行的,应该不存在 invocation 被释放的问题

我们的工程中好多因为这个问题崩溃的,但是目前也不知道什么原因,我想着使用pod更新到1.4.2,但是发现pod里面并没有搜索到1.4.2版本

是可以搜到的:https://cocoapods.org/pods/MessageThrottle 应该是你的本地缓存没更新?

好的,非常感谢,已经搜到,我们做灰度测试一下

from messagethrottle.

fangYaLei110 avatar fangYaLei110 commented on May 28, 2024

image
每次在View init的时候添加了一个间隔一秒刷新一次页面的防抖,使用的版本是1.4.0

from messagethrottle.

yulingtianxia avatar yulingtianxia commented on May 28, 2024

请问限频的对象有使用 KVO 么?如果有的话,可以升级到 1.4.1
如果依然没有解决问题,麻烦你可以提供一个可以复现的 demo 么?

from messagethrottle.

fangYaLei110 avatar fangYaLei110 commented on May 28, 2024

请问限频的对象有使用 KVO 么?如果有的话,可以升级到 1.4.1
如果依然没有解决问题,麻烦你可以提供一个可以复现的 demo 么?

image
限频的对象是一个tableView,没有使用KVO。

from messagethrottle.

yulingtianxia avatar yulingtianxia commented on May 28, 2024

有 crash.log 之类的完整日志么

from messagethrottle.

fangYaLei110 avatar fangYaLei110 commented on May 28, 2024

目前没有crash.log的完整日志,我使用的版本是1.4.1版本,我继续观察,如果有的话会发给你的

from messagethrottle.

yulingtianxia avatar yulingtianxia commented on May 28, 2024

好的,感谢

from messagethrottle.

carbon1985 avatar carbon1985 commented on May 28, 2024

会有可能出现这种可能吗?

在主循环的过程中,对象A被回收,同时之前某个时刻的延迟操作(MTPerformModeLast模式)也在这个循环中执行,这时候invokingLastInvocation执行的时候调用[self deallocObject]去访问被回收的对象A,从而导致崩溃。

static void mt_handleInvocation {
....
case MTPerformModeLast: {
invocation.selector = rule.aliasSelector;
[invocation retainArguments];
dispatch_async(rule.messageQueue, ^{
rule.lastInvocation = invocation;
if (now - rule.lastTimeRequest > rule.durationThreshold) {
rule.lastTimeRequest = now;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(rule.durationThreshold * NSEC_PER_SEC)), rule.messageQueue, ^{
[rule invokingLastInvocation];
});
}
});
break;
}
...
}

==================

  • (void)invokingLastInvocation {
    if (!self.isActive) {
    self.lastInvocation.selector = self.selector;
    }
    // 判断 target 现在的类型和之前 hook 时的类型的子类(或相同)
    // 如果判断成立,则可以正常 invoke;否则说明 isa 指针被其他程序修改过了,需要重新 apply rule,修正 isa。
    MTDealloc *mtDealloc = [self deallocObject];
    Class originalClass = object_getClass(self.target);
    BOOL valid = [originalClass isSubclassOfClass:mtDealloc.cls];
    if (!valid) {
    [self discard];
    [self apply];
    }
    [self.lastInvocation invoke];
    self.lastInvocation = nil;
    }

from messagethrottle.

yulingtianxia avatar yulingtianxia commented on May 28, 2024

会有可能出现这种可能吗?

在主循环的过程中,对象A被回收,同时之前某个时刻的延迟操作(MTPerformModeLast模式)也在这个循环中执行,这时候invokingLastInvocation执行的时候调用[self deallocObject]去访问被回收的对象A,从而导致崩溃。

static void mt_handleInvocation { .... case MTPerformModeLast: { invocation.selector = rule.aliasSelector; [invocation retainArguments]; dispatch_async(rule.messageQueue, ^{ rule.lastInvocation = invocation; if (now - rule.lastTimeRequest > rule.durationThreshold) { rule.lastTimeRequest = now; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(rule.durationThreshold * NSEC_PER_SEC)), rule.messageQueue, ^{ [rule invokingLastInvocation]; }); } }); break; } ... }

==================

  • (void)invokingLastInvocation {
    if (!self.isActive) {
    self.lastInvocation.selector = self.selector;
    }
    // 判断 target 现在的类型和之前 hook 时的类型的子类(或相同)
    // 如果判断成立,则可以正常 invoke;否则说明 isa 指针被其他程序修改过了,需要重新 apply rule,修正 isa。
    MTDealloc *mtDealloc = [self deallocObject];
    Class originalClass = object_getClass(self.target);
    BOOL valid = [originalClass isSubclassOfClass:mtDealloc.cls];
    if (!valid) {
    [self discard];
    [self apply];
    }
    [self.lastInvocation invoke];
    self.lastInvocation = nil;
    }

[invocation retainArguments] 会持有 target 的,应该不会被释放

from messagethrottle.

yulingtianxia avatar yulingtianxia commented on May 28, 2024

是否有其他线程可能会触发释放掉 tableView 呢 @fangYaLei110

from messagethrottle.

carbon1985 avatar carbon1985 commented on May 28, 2024

从我们的崩溃日志来看,这个对象的确是被释放了,然后invokingLastInvocation才会被调用

from messagethrottle.

yulingtianxia avatar yulingtianxia commented on May 28, 2024

虽然我还没复现 target 被释放的场景,但我先加了个保护兜底,可以使用 1.4.2 版本试试 @carbon1985 @fangYaLei110
想问下你们复现的工程里有使用 MRC 或者多线程读写这个对象的场景么?

from messagethrottle.

carbon1985 avatar carbon1985 commented on May 28, 2024

我们是用arc的,多线程读写应该不会有这个问题吧,我看了一下日志和崩溃堆栈,也都是在主线程上执行的

from messagethrottle.

yulingtianxia avatar yulingtianxia commented on May 28, 2024

主要是没有想到 target 被释放的原因,可能是在 retainArguments 方法调用前其他线程写操作导致 target 释放,但我没复现这种 case;我最担心的是 invocation 被释放导致 target 进而被释放,这意味着只针对 target 判空保护是不够的,参数列表也危险了。不过在这个场景下我看都是在主线程(rule.messageQueue)上执行的,应该不存在 invocation 被释放的问题

from messagethrottle.

fangYaLei110 avatar fangYaLei110 commented on May 28, 2024

主要是没有想到 target 被释放的原因,可能是在 retainArguments 方法调用前其他线程写操作导致 target 释放,但我没复现这种 case;我最担心的是 invocation 被释放导致 target 进而被释放,这意味着只针对 target 判空保护是不够的,参数列表也危险了。不过在这个场景下我看都是在主线程(rule.messageQueue)上执行的,应该不存在 invocation 被释放的问题

我们的工程中好多因为这个问题崩溃的,但是目前也不知道什么原因,我想着使用pod更新到1.4.2,但是发现pod里面并没有搜索到1.4.2版本

from messagethrottle.

fangYaLei110 avatar fangYaLei110 commented on May 28, 2024

这个崩溃在我们工程中目前存在70多个
image

from messagethrottle.

fangYaLei110 avatar fangYaLei110 commented on May 28, 2024

image
image
image
我们在初始化的时候进行了MTRule初始化,对mtRule_checkEnterChannel这个方法调用进行了防抖的操作,这个使用方式会存在什么问题吗

from messagethrottle.

yulingtianxia avatar yulingtianxia commented on May 28, 2024

image
image
image
我们在初始化的时候进行了MTRule初始化,对mtRule_checkEnterChannel这个方法调用进行了防抖的操作,这个使用方式会存在什么问题吗

这样没问题的

from messagethrottle.

yulingtianxia avatar yulingtianxia commented on May 28, 2024

主要是没有想到 target 被释放的原因,可能是在 retainArguments 方法调用前其他线程写操作导致 target 释放,但我没复现这种 case;我最担心的是 invocation 被释放导致 target 进而被释放,这意味着只针对 target 判空保护是不够的,参数列表也危险了。不过在这个场景下我看都是在主线程(rule.messageQueue)上执行的,应该不存在 invocation 被释放的问题

我们的工程中好多因为这个问题崩溃的,但是目前也不知道什么原因,我想着使用pod更新到1.4.2,但是发现pod里面并没有搜索到1.4.2版本

是可以搜到的:https://cocoapods.org/pods/MessageThrottle
应该是你的本地缓存没更新?

from messagethrottle.

yulingtianxia avatar yulingtianxia commented on May 28, 2024

请问后续还有碰到此问题么 @fangYaLei110

from messagethrottle.

Related Issues (17)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.