我试图在对象初始化期间卸载一些繁重的工作。我已经添加了一个状态属性,当我完全初始化我的对象的所有其他实例变量时,我会设置它。我通过以下示例简化了我的整个方法:
这是我的类 (Foo),它有我的初始化器:
//- 头文件
#import <Foundation/Foundation.h>
typedef void (^loadingCompletionBlock)(BOOL success);
typedef NS_ENUM(NSInteger, FooStatus) {
FooCreated,
FooReady,
FooFailed,
};
@interface Foo : NSObject
+ (id) withCompletionBlock:(loadingCompletionBlock) block;
@property (assign, nonatomic) FooStatus status;
@end
//- 实现文件
@implementation Foo
- (FooStatus) status {
__block FooStatus readStatus;
dispatch_sync([Foo concurrentLoadingQueue], ^{
readStatus = _status;
});
return readStatus;
}
+ (dispatch_queue_t)concurrentLoadingQueue
{
static dispatch_queue_t sharedQueue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedQueue = dispatch_queue_create("test.loadingQueue", DISPATCH_QUEUE_CONCURRENT);
});
return sharedQueue;
}
+ (id)withCompletionBlock:(loadingCompletionBlock) completed {
Foo* foo = [[Foo alloc] init];
foo.status = FooCreated;
dispatch_async([Foo concurrentLoadingQueue], ^{
for (int i=0; i<10000; i++)
{
NSLog(@"Running long tasks: %d", i);
}
foo.status = FooReady;
completed(YES);
NSLog(@"Foo status: %d (Background Thread)", foo.status);
});
return foo;
};
@end
然后我在主线程上调用以下代码:
Foo* foo = [Foo withCompletionBlock:^(BOOL success) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Foo status: %d (Main Thread)", foo.status);
});
}];
NSLog(@"Foo status: %d (Main Thread)", foo.status);
NSLog 会给我这些输出:
2014-10-01 07:09:49.606 TestConcurrentQueue[15610:60b] Foo status: 0 (Main Thread)
2014-10-01 07:09:52.818 TestConcurrentQueue[15610:1303] Running long tasks: 1
2014-10-01 07:09:52.818 TestConcurrentQueue[15610:1303] ......
2014-10-01 07:09:52.818 TestConcurrentQueue[15610:1303] Running long tasks: 9999
2014-10-01 07:09:52.818 TestConcurrentQueue[15610:60b] Foo status: 0 (Main Thread)
2014-10-01 07:09:52.818 TestConcurrentQueue[15610:1303] Foo status: 1 (Background Thread)
0 正在创建状态,1 已准备就绪,为什么我无法在我的主线程中获得正确的值?
最佳答案
我相信 foo 在完成 block 中是 nil 因为 foo 是作为原始方法调用的结果被创建和分配的。
一个简单的解决方案是将创建的对象作为参数传递给完成 block ,连同 BOOL。
更好的方法可能是使您的 withCompletionBlock: 成为实例方法而不是类方法。那么您的调用代码将类似于:
Foo* foo = [[Foo alloc] init];
[foo populateWithCompletionBlock:^(BOOL success) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Foo status: %d (Main Thread)", foo.status);
});
}];
NSLog(@"Foo status: %d (Main Thread)", foo.status);
这样,完成 block 中的 foo 引用了一个实际存在的对象。
Foo 的 init 方法将设置初始状态,仅此而已。
关于ios - 在多线程环境中获取正确的属性值的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26134541/
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog