我只是想,因为如果我创建其中两个然后将它们添加到NSArray中,你可以将块视为对象,是否有办法从数组中执行它们?
int (^Block_001)(void) = ^{ return 101; };
int (^Block_002)(void) = ^{ return 202; };
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil];
Run Code Online (Sandbox Code Playgroud)
编辑:更新清晰Per @ davedelong的优秀答案
int (^Block_001)(void) = [^{ return 101; } copy];
int (^Block_002)(void) = [^{ return 202; } copy];
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil];
[Block_001 release];
[Block_002 release];
Run Code Online (Sandbox Code Playgroud) 我正在使用AFNetworking来异步调用Web服务.这些呼叫中的一些必须链接在一起,其中呼叫A的结果由呼叫B使用,其由呼叫C使用,等等.
AFNetworking处理异步调用的结果,并在创建操作时设置成功/失败块:
NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/public_timeline.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(@"Public Timeline: %@", JSON);
} failure:nil];
[operation start];
Run Code Online (Sandbox Code Playgroud)
这会导致嵌套的异步调用块很快变得不可读.当任务不依赖于彼此而是必须并行执行并且执行取决于所有操作的结果时,它甚至更复杂.
似乎更好的方法是利用promises框架来清理控制流.
我遇到过MAFuture,但无法弄清楚如何最好地将它与AFNetworking集成.由于异步调用可能有多个结果(成功/失败)并且没有返回值,因此它似乎不是理想的选择.
任何指针或想法将不胜感激.
我有一个回调方法,我必须工作,但我想知道如何传递值.
我有的是这个:
@interface DataAccessor : NSObject
{
void (^_completionHandler)(Account *someParameter);
}
- (void) signInAccount:(void(^)(Account *))handler;
Run Code Online (Sandbox Code Playgroud)
上面的代码有效,但我想将值传递给方法.这看起来怎么样?就像是:
- (void) signInAccount:(void(^)(Account *))handler user:(NSString *) userName pass:(NSString *) passWord;
Run Code Online (Sandbox Code Playgroud)
?
我试图找出一种方法来typeof创建一个弱的引用,self以便在块中使用,以避免保留周期.
当我第一次读到这个时,似乎是使用惯例__block typeof(self) bself = self;,编译但是使用__block以避免保留周期不再起作用而__weak应该使用.
但是会__weak typeof(self) bself = self;导致错误:
类型'typeof(self)'(又名'TUAccountsViewController*const __strong')已经设置了保留属性
有没有办法使用typeof或其他调用一般创建一个弱引用self?
cocoa weak-references objective-c objective-c-blocks automatic-ref-counting
假设我需要与提供协议的类进行通信,并在操作完成时调用委托方法,如下所示:
@protocol SomeObjectDelegate
@required
- (void)stuffDone:(id)anObject;
- (void)stuffFailed;
@end
@interface SomeObject : NSObject
{
}
@end
Run Code Online (Sandbox Code Playgroud)
现在,我已经决定,虽然我可以创建另一个类实现stuffDone:委托方法,但我决定将该进程封装到一个块中,该块写在靠近SomeObject实例化,调用的地方等等.我怎么可能做这个?或者换句话说,如果你看看这对块著名的文章(在替换回调段); 我如何在SomeObject中编写一个接受各种类型的方法completionHandler:?
我对__block变量的语法有疑问.我知道你可以使用__block范围内的变量,因此它在块内不是只读的.然而,在苹果文档中的一个位置,我看到了另一种选择:
"在块中使用时,定义范围中的变量默认为只读.如果需要更改此类变量的值,可以使用特殊语法:
int count = 0;
float cumulativeValue = 0.0;
UpdateElements( a, N, ^(float element){
|count, cumulativeValue|
float value = factor * element;
++count;
cumulativeValue += value;
return value;
} );
Run Code Online (Sandbox Code Playgroud)
在此示例中,count和cumulativeValue在块内部被修改,因此它们包含在块作用域开头的逗号分隔的共享变量列表中.
这种语法似乎更清晰,我假设你可以修改你没有声明但仍在范围内的变量.但是,我还没有在其他任何地方看到这个,xCode编译器不喜欢我的基本块.这是合法的语法吗?
Apple的Grand Central Dispatch参考文献称:
"......如果你的应用程序需要在系统的Unix级别运行 - 例如,如果它需要操作文件描述符,Mach端口,信号或定时器.GCD不仅限于系统级应用程序,而是在你之前将它用于更高级别的应用程序时,您应该考虑Cocoa中提供的类似功能(通过NSOperation和块对象)是否更易于使用或更适合您的需求."
对于高级应用程序,我实际上无法想到这种情况,其中GCD的使用是强制性的,并且可以/不应该使用NSOperation.
有什么想法吗?
concurrency objective-c grand-central-dispatch ios objective-c-blocks
是否可以定义Objective-C块属性但在Xcode 4中仍然具有完整代码完成?
如果我使用typedef来定义块:
typedef void (^CompletionBlock)(MyObject *myObj);
然后定义属性:
@property (nonatomic, copy) CompletionBlock completionBlock;
然后@synthesize在调用setter时我没有得到完整代码完成的属性.Xcode将使用typedef,因此,代码完成不使用完整块语法完成块参数,它使用typedef.
如果我在标头中定义了一个使用完整块语法而不是typedef的方法原型:
@property (nonatomic, copy) void (^completionBlock)(MyObject *myObj);
然后我使用@synthesize,提供的setter接近使用完整的代码完成语法,但关键是它省略了参数名称:
[self setCompletionBlock:(void (^)(MyObject *)) { ... }
最后,如果我尝试@synthesize然后覆盖setter实现或将原型放在头文件中:
- (void)setCompletionBlock:(void (^)(MyObject *myObj))completionBlock {...}
会出现一条警告,指出属性类型与访问者类型不匹配.无论我如何尝试使用语法,我都无法定义块属性和具有完整代码完成语法的setter.我可以吃蛋糕吗?
谢谢!
我正在尝试为我工作的公司创建一个(网络)同步数组.虽然网络部分工作正常,但我已经陷入了一个问题.
我希望创建一个新队列使用dispatch_create_queue,我将添加两个不在主线程上运行的块,但是以串行方式运行,这意味着首先必须运行第一个块,然后是第二个块,而不是平行.
我已经阅读了苹果文档,但至少可以说是令人困惑的.
当我使用创建队列dispatch_queue_create然后使用时添加块(在它们被定义之后)dispatch_sync,我发现该块仍然在主线程上执行.
使用时dispatch_async,即当主线程上没有执行块时.
当我尝试使用dispatch_sync它们添加两个块时永远被阻止.
两个块似乎运行良好并且离开主线程的唯一时间是在调用时dispatch_async.
然而,我之所以选择GCD和同步方法,是因为我的印象是我正在创建一个新队列(因此是一个新线程),并且向该队列添加块只会阻塞一个,直到另一个完成执行.是不是这种情况,或者创建队列不保证代码不会在主线程上运行?
我仍然是objective-c中的块的新手,并想知道我的伪代码是否正确.我不确定是否只是删除观察者或者我必须调用removeObserver:name:object:
-(void) scan {
Scanner *scanner = [[Scanner alloc] init];
id scanComplete = [[NSNotificationCenter defaultCenter] addObserverForName:@"ScanComplete"
object:scanner
queue:nil
usingBlock:^(NSNotification *notification){
/*
do something
*/
[[NSNotificationCenter defaultCenter] removeObserver:scanComplete];
[scanner release];
}];
[scanner startScan];
}
Run Code Online (Sandbox Code Playgroud)
更新:我EXC_BAD_ACCESS从这个区块收到间歇性,所以这不可能是正确的.
objective-c ×10
ios ×4
cocoa ×3
afnetworking ×1
callback ×1
cocoa-touch ×1
concurrency ×1
fifo ×1
iphone ×1
methods ×1
nsarray ×1
xcode ×1
xcode4 ×1