我咨询了#34; Handle Classes"
部分http://uk.mathworks.com/help/distcomp/objects-and-handles-in-parfor-loops.html
并写下:
parfor j = 1:length(stores)
store = stores(j);
dataj = somefunction(store.someproperty, data(data.store == store.id, :));
stores(j) = store.dosomething(dataj);
end
其中dosomething
修改了store
的状态。 (store
是句柄类)。
循环适用于for
;切换到parfor
,store
对象的状态无法更新。
这是Matlab的文档问题,还是我对它的理解?
UPD。编辑评论很痛苦,所以我继续在这里。这是一个玩具类,有两种方法,修改对象的状态。
classdef shop < handle
properties
stock = 10
end
methods
function clearstock(obj)
obj.stock = 0;
end
function[obj] = clearstock2(obj)
obj.stock = 0;
end
end
end
现在测试脚本:
n = 1;
shops = repmat(shop, n, 1);
sprintf('Stock before: %d', shops(1).stock)
% A
parfor i = 1:n
shops(i).clearstock;
end
sprintf('Stock after: %d', shops(1).stock)
% B
shops = repmat(shop, n, 1);
parfor i = 1:n
shops(i).clearstock2;
end
sprintf('Stock after: %d', shops(1).stock)
% C
shops = repmat(shop, n, 1);
parfor i = 1:n
shop = shops(i);
shop.clearstock;
shops(i) = shop;
end
sprintf('Stock after: %d', shops(1).stock)
% D
shops = repmat(shop, n, 1);
parfor i = 1:n
shop = shops(i);
shop = shop.clearstock2;
shops(i) = shop;
end
sprintf('Stock after: %d', shops(1).stock)
(A,B)保持状态不变,(C,D)按预期/广告工作。现在,我的真实&#39;非玩具&#39;对象&#39; state是内置类和自定义类的混合。 (未更新的state元素是数值数组的单元格数组)。我想知道后者是后者吗?
UPD2。用户定义的句柄类作为属性 - 仍然按预期工作。
%MANAGER.M
classdef manager < handle
properties
name
salary = 100000;
end
methods
function[obj] = manager(name)
obj.name = name;
end
function giveraise(obj)
obj.salary = 200000;
end
function[obj] = giveraise2(obj)
obj.salary = 300000;
end
end
end
%SHOP.M
classdef shop < handle
properties
stock = 10;
manager = manager('John Doe');
end
methods
function clearstock(obj)
obj.stock = 0;
end
function[obj] = clearstock2(obj)
obj.stock = 0;
end
end
end
clc
n = 1;
shops = repmat(shop, n, 1);
sprintf('Stock before: %d', shops(1).stock)
sprintf('Salary before: %d', shops(1).manager.salary)
% A2
parfor i = 1:n
shops(i).clearstock;
shops(i).manager.giveraise;
end
sprintf('Stock after: %d', shops(1).stock)
sprintf('Salary after: %d', shops(1).manager.salary)
% B2
shops = repmat(shop, n, 1);
parfor i = 1:n
shop = shops(i);
shop.clearstock;
shop.manager.giveraise;
shops(i) = shop;
end
sprintf('Stock after: %d', shops(1).stock)
sprintf('Salary after: %d', shops(1).manager.salary)
% C2
shops = repmat(shop, n, 1);
parfor i = 1:n
shop = shops(i);
shop.manager = shop.manager.giveraise2;
shop = shop.clearstock2;
shops(i) = shop;
end
sprintf('Stock after: %d', shops(1).stock)
sprintf('Salary after: %d', shops(1).manager.salary)
那是关于价值类的吗?
UPD3。不,shop
属性的用户定义值类工作正常。我停下来,直到我能想出一个可重复的例子。
答案 0 :(得分:1)
这有点棘手,因为我们没有看到整个代码,但我最好的猜测是dosomething
方法不返回修改后的store
对象实例,并且而是返回别的东西。当您使用通常的for
循环运行它时,此方法实际上更改了store
句柄对象。但是,当您使用parfor
运行它时,唯一在循环外持久保存的是dosomething
的返回值,该值已分配给stores(j)
。请尝试以下方式:
parfor j = 1:length(stores)
store = stores(j);
dataj = somefunction(store.someproperty, data(data.store == store.id, :));
store.dosomething(dataj);
stores(j) = store;
end
作为替代方案,请确保dosomething
返回对象本身,即
function obj = dosomething(obj, dataj)
% ...
end
答案 1 :(得分:0)
问题解决了,它位于所呈现的代码之外。
parfor
循环位于函数simulateoneday
内,该函数在循环中从函数simulatemultipledays
调用。 simulatemultipledays
会将simulateoneday
个store
对象传递给parfor
,然后转到parfor
。
simulatemultipledays
不是'重置'对象的状态 - 相反,它是simulateoneday
- - - simulateoneday
段。当我'simulatemultipledays
吸收for
时,事情开始发挥作用。
我想知道我是否已经通过引用传递了值传递,但是嘿,代码在parfor
下工作得很好 - 它是 public class CategoryActivity extends BaseActivity implements View.OnClickListener {
private RelativeLayout mReLayout;
private byte[] mImageByte;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_1);
addControl();
addEventOnClick();
mReLayout.setDrawingCacheEnabled(true);
}
private void addEventOnClick() {
findViewById(R.id.layout_category_1).setOnClickListener(this);
}
private void addControl() {
mReLayout = (RelativeLayout) findViewById(R.id.relative_category);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.layout_category_1:
startActivity();
break;
default:
break;
}
}
private void startActivity() {
Bitmap layoutBitmap = Bitmap.createBitmap(mReLayout.getWidth(), mReLayout.getHeight(), Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(layoutBitmap);
mReLayout.draw(canvas);
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
layoutBitmap.compress(Bitmap.CompressFormat.PNG, 90, bStream);
mImageByte = bStream.toByteArray();
Intent mIntent = new Intent(Activity1.this, Activity2.class);
mIntent.putExtra(Constant.BYTE_IMAGE, mImageByte);
startActivity(mIntent);
}
}
,它破坏了东西