Ion thread initialization on iOS

I have a view controller that I want to lazily initialize and after initialization use the same copy whenever possible (I don't use singleton since I want to delete it from memory in the end), I use getter to do so my code is as follows:

@property (retain) UIViewController *myController ... @synthesize myController = _myController; ... - (UIViewController *)myController { if (!_myController) { // Evaluation _myController = [[MyViewController alloc] init]; // Object Creation } return _myController; } 

This works, but it is not thread safe, and if more than one thread evaluates to true before creating the object, I will have a memory leak. One solution I've tried is @synchronized code, but I'm not sure how to do it right.

This works, (lockForMyController is a simple NSString), but makes this section of code much slower:

  - (UIViewController *)myController { @synchronized(self.lockForMyController){ if (!_myController) { _myController = [[MyViewController alloc] init]; } } return _myController; } 

I was wondering if there is another way to achieve a lazy initialized, thread safe property?

+6
source share
1 answer

This solution works.

Please note that this solution only works if myController accesses the background thread for the first time. It will be inhibited if called in the main thread.

Do you want to use gcd. The key serializes the creation of an object, so that regardless of threads starting with a block, it will be created only once.

 - (UIViewController *)myController if (_myController == nil) { dispatch_sync(dispatch_get_main_queue(), ^ { if (_myController == nil) _myController = [[MyViewController alloc] init]; }); } return _myController; } 

Here, even if multiple threads execute a block, block execution is serialized to the main thread, and only one MyViewController can be created.

You will not see a performance hit if the object is not equal to zero.

Since the property is implicitly atomic, this means that the value will be automatically implemented in the installer. This should make it suitable for mixing with your custom receipt, as it will automatically change the value to _myController.

http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW2

However, you can still get into a race state when you set a value in one thread, but get access to it in another. Each time you set a value, you probably want to make sure and do something like this:

dispatch_sync (dispatch_get_main_queue (), ^ {self.myController = {newValueOrNil}});

This will allow you to serialize calls to setter methods without having to reinvent the wheel for atomic setters, which is very difficult to do right.

This solution does not work.

Do you want to use gcd.

http://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/c/func/dispatch_once

See this singles post. I know you don't need a singleton, but it demonstrates how to use this method. You can easily adapt it.

Create Singleton Using GCD Manager in Objective-C

+10
source

Source: https://habr.com/ru/post/899844/


All Articles