快速问题:我ViewController的IBOutletfor aUILabel会ViewController's view自动保留对标签的强引用吗?而且,如果我以编程方式创建一个UIPopoverController ivarinViewController并UIPopoverController ivar以编程方式将其放在屏幕上,也会ViewController's view自动保留对此的强引用吗?
目前,我正在通过以下方式获取核心数据
CoreDataStack.sharedIntance.backgroundContext.performBlock({
let fetchRequest = NSFetchRequest(entityName: "Schedule")
let sortDescriptor = NSSortDescriptor(key: "startTime", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
var result = [Schedule]()
mainContext.performBlockAndWait { [unowned self] in
do {
result = try mainContext.executeFetchRequest(fetchRequest) as! [Schedule]
success?(result)
} catch {
print("error is \(error)")
}
}
})
Run Code Online (Sandbox Code Playgroud)
我收到一个错误
闭包中对属性 mainContext 的引用需要显式 self 以使捕获语义显式
我注意到一些解决方案,它们self为块中的属性添加了。
这样做好还是我们应该创建一个weak or unowned以避免保留循环以及处理这种情况的最佳方法是什么。
所以这是我的错误代码我认为这个错误有一些困难,我查看了论坛但找不到。
而且...我的手机上有错误(使用kivy launcher python 3,当我使用 buildozer 构建时)但我的电脑上没有错误(ubuntu 18.0.4 和 windows 10) 据我了解,错误来自垃圾删除引用的收集器,并且代码尝试在垃圾收集器之后访问该引用。但我不确定我是否真的了解垃圾收集器
我试过的:
id: id.__self__
Run Code Online (Sandbox Code Playgroud)
在我的 kv 文件中
self.refs = [
self.id.__self__,
self.id.__self__]
Run Code Online (Sandbox Code Playgroud)
- 使用 ErrorHandler 来处理错误,但错误永远出现
我认为导致错误的原因,但我不知道如何解决:
我用来向服务器发送请求的时钟,但我不知道为什么(self.requestClient 是一个发送请求的函数):
C = Clock.schedule_interval(self.requestClient, 5)
kivy 时钟文档中的此信息:
重要的
回调是弱引用:您负责保持对原始对象/回调的引用。如果您不保留引用,则 ClockBase 将永远不会执行您的回调
错误 :
[ERROR ] Exception catched by ExceptionHandler
05-07 11:27:45.694 2788 2823 I python : Traceback (most recent call last):
05-07 11:27:45.694 2788 2823 I python : File path/kivy-launcher/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/launcher/kivy/core/window/window_sdl2.py", …Run Code Online (Sandbox Code Playgroud) 我有一个类,它的实例被底层 flatform 初始化和使用。
class MyAttributeConverter implements AttributeConverter<XX, YY> {
public YY convertToDatabaseColumn(XX attribute) { return null; }
public XX convertToEntityAttribute(YY dbData) { return null; }
}
Run Code Online (Sandbox Code Playgroud)
没有错,我想我需要添加一些静态方法以用作方法引用。
private static MyAttributeConverter instance;
// just a lazy-initialization;
// no synchronization is required;
// multiple instantiation is not a problem;
private static MyAttributeConverter instance() {
if (instance == null) {
instance = new MyAttributeConverter();
}
return instance;
}
// do as MyAttributeConverter::toDatabaseColumn(xx)
public static YY toDatabaseColumn(XX attribute) {
return instance().convertToDatabaseColumn(attribute);
}
public static …Run Code Online (Sandbox Code Playgroud) 我的理解是,在对Targeta 的所有强引用WeakReference都设置为 null 并调用 GC 后,该弱引用不应再存在。
然而,下面的代码似乎没有遵循这个期望:
static void Main(string[] _) {
var person = new Person();
var wr = new WeakReference(person);
person = null;
// We should have access to the person here
if (wr.Target is Person shouldExist)
{
Console.WriteLine($"Person exists! IsAlive: {wr.IsAlive}.");
shouldExist = null;
}
else
{
Console.WriteLine($"Person does not exist :( IsAlive: {wr.IsAlive}.");
}
// Invoke GC.Collect.
GC.Collect();
if (wr.Target is Person shouldNotExist)
{
Console.WriteLine("This person should have been garbage collected");
Console.WriteLine($"IsAlive: …Run Code Online (Sandbox Code Playgroud) 我暂时写了这个方法:
public static Func<T> WeakCacheFor<T>( Func<T> provider ) where T: class
{
var cache = new WeakReference(null);
return () => {
var x = (T)cache.Target;
if( x == null )
{
x = provider();
cache.Target = x;
}
return x;
};
}
Run Code Online (Sandbox Code Playgroud)
所以有点背景:
我有一些冗长的遗留方法,看起来有点像这样:
var id = GetDatabaseId();
if(a){
var data = GetLoader().Init(id).GetData(); // expensive!
// do stuff with data
}
if(b){
// don't load data
}
... lots more variations, some contain GetLoader().Init(id).GetData(); some don't....
Run Code Online (Sandbox Code Playgroud)
我的潜在解决方案是这样做:
var id = …Run Code Online (Sandbox Code Playgroud) 在下面的代码中,我创建了一个Pen对象,并将其颜色初始化为白色.在Pen的构造函数中,在将字段'penColor'设置为传递给构造函数的值之后,我更新了一个全局静态弱hashmap,我将其保存在KEY是'this pointer - 在我的情况下是Pen,以及value是另一个weakhashmap,其KEY是字符串"penColor",其值是对penColor成员字段的引用.
接下来,我的代码通过调用Pen的setColor函数来更新Pen的颜色.我本以为在这次更新之后,如果我在我的weakhashmap中查找Pen对象的颜色字段,它会反映新的颜色,但事实并非如此.有人可以解释为什么会这样吗?
package weakhashmaptest;
import java.awt.Color;
import java.util.WeakHashMap;
import java.util.Iterator;
public class Main {
static WeakHashMap <Object, WeakHashMap>ownerMap = new WeakHashMap<Object, WeakHashMap>();
public static void main(String[] args) {
Pen r = new Pen(Color.WHITE);
Iterator i = ownerMap.keySet().iterator();
while(i.hasNext()) {
Object key = i.next();
System.out.println("\telement of hashmap is : " +ownerMap.get(key));
}
r.setColor(Color.BLACK);
System.gc();
i = ownerMap.keySet().iterator();
while(i.hasNext()) {
Object key = i.next();
System.out.println("\telement of hashmap is : " +ownerMap.get(key));
}
}
public static void mapUpdate(Object owner, Object …Run Code Online (Sandbox Code Playgroud) 我一直试图WeakReference在我的Android项目中使用,但我从来没有取得任何成功.现在我真的需要它,因为我正在处理旧设备,我必须尽可能地保持内存清洁.
无论如何,我有一个数组,其中包含大约1000个不同字符串列表.我需要加载它,然后在其中找到一个字符串.
这就是我目前使用它的方式:
String[] campaignList = context.getResources().getStringArray(R.array.campaignList);
WeakReference<String[]> weakCampaignList = new WeakReference<String[]>(campaignList);
Run Code Online (Sandbox Code Playgroud)
这是正确的使用方式WeakReference吗?如果是,那么我不明白的是阵列正在水合,String[]然后我把它传递给了WeakReference.那么这是不是意味着我在分配给一个阵列的内存上有2个点?或者我完全误解了这个WeakReference概念?
我在所有资源中发现的一个非常好的资源就是这个:
http://neverfear.org/blog/view/150/Strong_Soft_Weak_and_Phantom_References_Java
编辑:
我的代码没有问题.只需要知道我在性能方面是否正确.
for (int i = 0; i < weakCampaignList.get().length; i++) {
Log.d(TAG,"weakCampaignList: "+weakCampaignList.get()[i]);
}
Run Code Online (Sandbox Code Playgroud)
我的整个方法
public static String getTheCampaign(String country, Context context) {
String campaign = "";
campaign = "annual_subscription_" + country;
String[] campaignList = context.getResources().getStringArray(
R.array.campaign_list);
ArrayList<WeakReference<String>> weakCampaignList = new ArrayList<WeakReference<String>>();
for (String s : campaignList) {
weakCampaignList.add(new WeakReference<String>(s));
}
if (country.equals("") || …Run Code Online (Sandbox Code Playgroud) 这是使用弱参数的一个小例子:
@interface MYTestObject : NSObject
@end
@implementation MYTestObject {
void(^_block)(void);
}
- (void)dealloc {
NSLog(@"DEALLOC!");
}
- (id)init {
if (self = [super init]) {
[self doSomethingWithObject:self];
}
return self;
}
- (void)doSomethingWithObject:(id __weak /* <- weak argument! */)obj {
_block = ^{
NSLog(@"%p", obj);
};
}
@end
Run Code Online (Sandbox Code Playgroud)
它有效:-dealloc被称为!此外,如果你删除__weak你将获得一个保留周期,这是绝对正确的.
不知道,如果这只是一个副作用,使用弱论点是完全不安全的吗?或者它是一个特定的行为,我只是一个糟糕的谷歌用户?
arguments weak-references objective-c automatic-ref-counting
我写了这段代码:
dog joe = new dog();
WeakReference wr = new WeakReference(joe);
if (wr.IsAlive)
{
Console.WriteLine("Yes,first time");
}
else
{
Console.WriteLine("No,first time");
}
GC.Collect();
if (wr.IsAlive)
{
Console.WriteLine("Yes,second time");
}
else
{
Console.WriteLine("No,second time");
}
Run Code Online (Sandbox Code Playgroud)
我期望得到这样的结果: 是的,第一次 否,第二次
但似乎 GC 没有收集我的 WeakReference 的目标(joe)。结果是: 是的,第一次 是的,第二次
我的问题是什么?..我是否误解了弱引用?
谁能告诉我为什么我们使用guard let self = self?
我在阅读GCD时已经看过这段代码,我无法弄清楚那条特定的线路是做什么的.
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let self = self else {
return
}
// ...
}
Run Code Online (Sandbox Code Playgroud) 我想知道如何在C中定义一个对象,其引用将为null?
// definition of foo
...
void * bar = &foo; // bar must be null
Run Code Online (Sandbox Code Playgroud)
有一些方法我可以找到它,但没有一个符合我的需要.
__attribute__((weak)) extern int foo; //not working with cygwin/gcc 3.4
__attribute__((at(0))) int foo; //only with rvds
#define foo (*(int*) 0) //cannot be embedded in a macro
Run Code Online (Sandbox Code Playgroud)
实际上,我更喜欢符合标准的解决方案(c99),但任何正常工作都可以.
编辑:这样做的原因是bar不会总是为空.这是一个更相关的例子:
// macro that will define foo to a real object or to *null
DECL(foo);
int * bar = &foo;
if(bar) {
// we can call func
func(bar);
} else {
// bar undefined
exit(-1);
}
Run Code Online (Sandbox Code Playgroud)
当然这仍然不是很相关,因为我可以在我的条件下使用#if.该项目实际上涉及大型结构,大量文件,一些编译器,一些cpu目标,以及许多程序员,他们生成的错误概率指数与他们使用的语法的复杂性呈指数关系.这就是为什么我想要一个简单的宏来声明我的foo对象.
对于一个玩具示例,假设我有一个时钟小部件:
\n{\n const clockElem = document.getElementById(\'clock\');\n\n const timefmt = new Intl.DateTimeFormat(\n \'default\', { timeStyle: \'medium\', });\n\n setInterval(() => {\n const d = new Date;\n console.log(\'tick\', d, clockElem);\n clockElem.querySelector(\'p\').innerHTML =\n timefmt.format(d);\n }, 1000);\n\n clockElem.querySelector(\'button\')\n .addEventListener(\'click\', ev => {\n clockElem.remove();\n });\n}Run Code Online (Sandbox Code Playgroud)\r\n<div id="clock">\n <button>Remove</button>\n <p></p>\n</div>Run Code Online (Sandbox Code Playgroud)\r\n当我单击按钮删除时钟时,setInterval回调仍然被调用。回调闭包强力持有 DOM 节点,这意味着它的资源无法被释放。还有来自按钮事件处理程序的循环引用;尽管也许这个可以由 engine\xe2\x80\x99s 循环收集器处理。话又说回来,也许不是。
不用担心:我可以创建一个辅助函数,确保闭包仅通过弱引用保存 DOM 节点,并抛出FinalizationRegistry来清理计时器。
const weakCapture = (captures, func) => {\n captures = captures.map(o => new WeakRef(o));\n …Run Code Online (Sandbox Code Playgroud)weak-references ×13
c# ×3
java ×3
objective-c ×3
closures ×2
ios ×2
.net ×1
android ×1
arguments ×1
c ×1
c++ ×1
caching ×1
dom ×1
iphone ×1
javascript ×1
kivy ×1
linker ×1
performance ×1
python ×1
swift ×1
swift2 ×1
view ×1
weakhashmap ×1