Objective c 区块和中央调度,代码上的差异?
这些例子有什么不同?我不明白为什么它们不同,提供不同的结果。正如我所看到的,块中的代码将在某个时候在主线程中运行,第一个代码提供的结果是foo或bar,不确定原因和时间Objective c 区块和中央调度,代码上的差异?,objective-c,objective-c-blocks,grand-central-dispatch,Objective C,Objective C Blocks,Grand Central Dispatch,这些例子有什么不同?我不明白为什么它们不同,提供不同的结果。正如我所看到的,块中的代码将在某个时候在主线程中运行,第一个代码提供的结果是foo或bar,不确定原因和时间 NSString *myString = @"foo"; dispatch_async (dispatch_get_main_queue(), ^{ NSLog (@"%@", myString); }); myString = @"bar"; 第二: NSMutableString *myString = [NSM
NSString *myString = @"foo";
dispatch_async (dispatch_get_main_queue(), ^{
NSLog (@"%@", myString);
});
myString = @"bar";
第二:
NSMutableString *myString = [NSMutableString stringWithString:@"foo"];
dispatch_async (dispatch_get_main_queue(), ^{
NSLog (@"%@", myString);
});
[myString setString:@"bar"];
这是相当微妙的(也就是说,最好构造代码以避免回答以下问题:)
在第一个示例中,块捕获指向文本常量NSString的指针的常量副本。然后更新原始指针以指向新字符串。块应该在以后的某个任意点从主线程打印“foo”
在第二个示例中,该块捕获指向可变NSString的指针的常量副本。然后更新可变NSString,使其具有不同的内容。如果代码在非主线程/队列上运行,块可能会打印“foo”,可能会打印“bar”,或者在更改时由于打印字符串而崩溃。如果块位于主线程/队列上,则它将打印“bar”。这是非常微妙的(即,最好构造代码以避免回答此问题:)
在第一个示例中,块捕获指向文本常量NSString的指针的常量副本。然后更新原始指针以指向新字符串。块应该在以后的某个任意点从主线程打印“foo”
在第二个示例中,该块捕获指向可变NSString的指针的常量副本。然后更新可变NSString,使其具有不同的内容。如果代码在非主线程/队列上运行,块可能会打印“foo”,可能会打印“bar”,或者在更改时由于打印字符串而崩溃。如果块位于主线程/队列上,则它将打印“bar”。区别在于:
- 在第一种情况下,您有两个不同的对象,
和@“foo”
@“bar”
首先指向myString
,然后将其更改为指向@“foo”
@“bar”
- 在第二种情况下,您有一个对象,
NSMutableString
始终指向该对象。但是,该myString
的内容将从NSMutableString
更改为的“foo”
的“bar”
@“foo”
时捕获myString
。稍后将其指向@“bar”
的更改不会影响块中捕获的副本
在第二种情况下,块捕获myString
的值。但是,它不会捕获myString
指向的对象的状态。因此,您可以更改对象的内容,块在运行时将看到新内容
顺便说一下,这与调度\u async
、GCD或多线程无关。如果直接同步运行块,您将看到相同的效果
NSString *myString = @"foo";
void (^myBlock)(void) = ^{
NSLog (@"%@", myString);
};
myBlock(); // prints "foo"
myString = @"bar";
myBlock(); // prints "foo"
NSMutableString *myString = [NSMutableString stringWithString:@"foo"];
void (^myBlock)(void) = ^{
NSLog (@"%@", myString);
};
myBlock(); // prints "foo"
[myString setString:@"bar"];
myBlock(); // prints "bar"
区别在于:
- 在第一种情况下,您有两个不同的对象,
和@“foo”
@“bar”
首先指向myString
,然后将其更改为指向@“foo”
@“bar”
- 在第二种情况下,您有一个对象,
NSMutableString
始终指向该对象。但是,该myString
的内容将从NSMutableString
更改为的“foo”
的“bar”
@“foo”
时捕获myString
。稍后将其指向@“bar”
的更改不会影响块中捕获的副本
在第二种情况下,块捕获myString
的值。但是,它不会捕获myString
指向的对象的状态。因此,您可以更改对象的内容,块在运行时将看到新内容
顺便说一下,这与调度\u async
、GCD或多线程无关。如果直接同步运行块,您将看到相同的效果
NSString *myString = @"foo";
void (^myBlock)(void) = ^{
NSLog (@"%@", myString);
};
myBlock(); // prints "foo"
myString = @"bar";
myBlock(); // prints "foo"
NSMutableString *myString = [NSMutableString stringWithString:@"foo"];
void (^myBlock)(void) = ^{
NSLog (@"%@", myString);
};
myBlock(); // prints "foo"
[myString setString:@"bar"];
myBlock(); // prints "bar"
下面是首次创建块并调用
dispatch\u async
时的情况:
--NSString-------
| "Foo" |
-----------------
^ ^
| |
myString GCD Block
下面是它在函数末尾的表现。您正在将myString
分配给一个全新的NSString实例,与块捕获的实例不同:
--NSString------- --NSString-------
| "Foo" | | "Bar" |
----------------- -----------------
^ ^
| |
GCD Block myString
--NSMutableString----
| "Bar" |
---------------------
^ ^
| |
myString GCD Block
在这种情况下,无论何时执行块,块都将始终打印“Foo”
第二个例子类似地开始:
--NSMutableString----
| "Foo" |
---------------------
^ ^
| |
myString GCD Block
除了修改块捕获的相同NSMutableString实例外:
--NSString------- --NSString-------
| "Foo" | | "Bar" |
----------------- -----------------
^ ^
| |
GCD Block myString
--NSMutableString----
| "Bar" |
---------------------
^ ^
| |
myString GCD Block
该块可以打印“Foo”或“Bar”,具体取决于它执行的时间。如果块打印“Bar”,则表示该块是在您修改NSMutableString实例后执行的。以下是首次创建块并调用
dispatch\u async
时的情况:
--NSString-------
| "Foo" |
-----------------
^ ^
| |
myString GCD Block
下面是它在函数末尾的表现。您正在将myString
分配给一个全新的NSString实例,与块捕获的实例不同:
--NSString------- --NSString-------
| "Foo" | | "Bar" |
----------------- -----------------
^ ^
| |
GCD Block myString
--NSMutableString----
| "Bar" |
---------------------
^ ^
| |
myString GCD Block
在这种情况下,无论何时执行块,块都将始终打印“Foo”
第二个例子类似地开始:
--NSMutableString----
| "Foo" |
---------------------
^ ^
| |
myString GCD Block
除了修改块捕获的相同NSMutableString实例外:
--NSString------- --NSString-------
| "Foo" | | "Bar" |
----------------- -----------------
^ ^
| |
GCD Block myString
--NSMutableString----
| "Bar" |
---------------------
^ ^
| |
myString GCD Block
该块可以打印“Foo”或“Bar”,具体取决于它执行的时间。如果块打印“Bar”,则表示该块是在您修改NSMutableString实例后执行的。欢迎来到多线程世界。这实际上不是多线程问题。所有这些代码都可以在主线程上运行。欢迎来到多线程世界。这真的不是多线程问题。所有这些代码都可以在主线程上运行。