Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 使用GCD修改对象/外部变量的最干净、最安全的方法_Objective C_Grand Central Dispatch - Fatal编程技术网

Objective c 使用GCD修改对象/外部变量的最干净、最安全的方法

Objective c 使用GCD修改对象/外部变量的最干净、最安全的方法,objective-c,grand-central-dispatch,Objective C,Grand Central Dispatch,Apple建议使用静态全局或_块存储类型修改外部变量 dispatch_async()需要不带参数的块 从该块中修改self.prop最干净、最安全的方法是什么 使用原子设置器 把这个街区围成一个街区 调度回主线程 我的设想: 该块正在发出网络请求。 当它完成后,我必须解析一些返回的数据,并在几个不同的对象上设置属性,以便我可以发出后续的网络请求。 这些块正在异步处理,但根据用户输入,第二个块可以提交到队列,其中包含第一个块所需的数据。 这是我想做的 @implementation MyNetw

Apple建议使用静态全局或_块存储类型修改外部变量

dispatch_async()需要不带参数的块

从该块中修改self.prop最干净、最安全的方法是什么

使用原子设置器

把这个街区围成一个街区

调度回主线程

我的设想: 该块正在发出网络请求。 当它完成后,我必须解析一些返回的数据,并在几个不同的对象上设置属性,以便我可以发出后续的网络请求。 这些块正在异步处理,但根据用户输入,第二个块可以提交到队列,其中包含第一个块所需的数据。 这是我想做的

@implementation MyNetworkManager {
  dispatch_queue_t op_queue;
  NSURL *_redirectedURL;
}

void (^initPageOperation) (void) = ^(void) {
  NSURL *url;
  NSMutableURLRequest *urlRequest;
  url = [NSURL URLWithString:domain];
  urlRequest =
  [NSMutableURLRequest requestWithURL:url
                          cachePolicy:NSURLRequestUseProtocolCachePolicy
                      timeoutInterval:5];
  [urlRequest setHTTPMethod:@"GET"];

  NSData *data = nil;
  NSURLResponse *urlResponse = nil;
  NSError *err = nil;

  data = [NSURLConnection sendSynchronousRequest:urlRequest
                               returningResponse:&urlResponse
                                           error:&err];

  if (urlResponse) {
     if (![urlResponse.URL isEqual:url]) {
            //Here's where I want to set the redirectedURL.
            _redirectedURL = urlResponse.URL;
     }
   }
};

Apple建议修改变量的内容。如果改为修改变量引用的对象(
self.prop
,在您的情况下),那么问题在使用或不使用GCD的情况下都是一样的-如何编写属性/方法以使其线程安全


对此有多种答案(
@synchronized{}
dispatch\u semaphore\u X()
NSLock
,…),研究确保线程安全并找到满足您需求的方法。

苹果的建议与修改变量内容有关。如果改为修改变量引用的对象(
self.prop
,在您的情况下),那么问题在使用或不使用GCD的情况下都是一样的-如何编写属性/方法以使其线程安全

对此有多种答案(
@synchronized{}
dispatch\u semaphore\u X()
NSLock
,…),研究确保线程安全并找到满足您需要的方法。

您说过:

Apple建议使用静态全局或
\u块
存储类型修改外部变量

我不确定我是否会这样说。我认为更合乎逻辑的思考方式是“如果您想修改一个方法的局部变量,您可以在该变量的声明上使用
\u块
限定符,否则就不需要该限定符”。简而言之,类实例变量(或属性)、
静态变量、全局变量等不需要
\u块
限定符

你接着说:

dispatch_async()需要不带参数的块

当然,这是真的。但是,同样,如果您正在编写自己的完成块,您可以将它们定义为具有参数。或者,您可以使用具有自己类型的完成块和自己的参数的API调用。例如:

[NSURLConnection sendAsynchronousRequest:request
                                   queue:queue
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                           // here you can initiate the parse of the data,
                           // capturing the url from the response, or examining
                           // the error
                       }];
completionHandler
是一个接受参数的块

因此,是的,一个简单的
dispatch\u async
(或
NSOperationQueue
等价物,
addOperationWithBlock
)不带参数,当您开始编写自己的完成块时,您通常会编写带参数的块

从该块中修改
self.prop
最干净、最安全的方法是什么

从技术上讲,您可以修改它。不过,诀窍是,如果您有多个线程可能同时访问该类,那么您可以通过或(您创建的串行队列或主队列)之一将您的交互与该类属性同步

使用原子设置器

这只适用于。不过,在处理对象时,atomic setter不会给您带来太多好处。您需要一些其他机制来同步与变量的交互,如上面所述

把这个街区围成一个街区

某种程度上,但从技术上讲,并不是将其包装在一个块中以提供线程安全,而是将该块分配到一个串行队列(并确保与该属性的所有其他交互都在同一个串行队列上完成)

调度回主线程

在某些简单的情况下,是的,这也可以完成工作。但是,请确保您没有将任何非常耗时的任务分派到主线程,否则您的UI可能会受到影响(或更糟)

我有一个假设情景。总的来说,我正在努力理解块的最佳实践

有这么多不同的模式,一个假设性的问题很难回答,因为细节完全不同,具体取决于业务需求。为了获得最佳实践,我鼓励您观看WWDC视频Rob Mayoff。您还可以查看WWDC 2012。这些概念也建立在早期视频的基础上,如WWDC 2011视频,如和。

您说过:

Apple建议使用静态全局或
\u块
存储类型修改外部变量

我不确定我是否会这样说。我认为更合乎逻辑的思考方式是“如果您想修改一个方法的局部变量,您可以在该变量的声明上使用
\u块
限定符,否则就不需要该限定符”。简而言之,类实例变量(或属性)、
静态变量、全局变量等不需要
\u块
限定符

你接着说:

dispatch_async()需要不带参数的块

当然,这是真的。但是,同样,如果您正在编写自己的完成块,您可以将它们定义为具有参数。或者,您可以使用具有自己类型的完成块和自己的参数的API调用。例如:

[NSURLConnection sendAsynchronousRequest:request
                                   queue:queue
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                           // here you can initiate the parse of the data,
                           // capturing the url from the response, or examining
                           // the error
                       }];
completionHandler
是一个接受参数的块

因此,是的,一个简单的
dispatch\u async
(或
NSOperationQueue
等价物,
addOperationWithBlock
)不带参数,当您开始编写自己的完成块时,您通常会编写带参数的块

修改
self.prop最干净最安全的方法是什么