I'm using GCD to add thread-safety to a class.
Some public methods of my class are called by other public methods in the class. However, this leads to the re-entrant locking problem: if I protect the appropriate publicly visible methods with synchronous GCD blocks (in some cases), the re-use means sometimes I'll be trying to run anther synchronous block on the current queue, which leads to deadlock.
What's the most elegant solution? An obvious approach is to have internal versions of the appropriate methods, without any GCD blocks, and external public versions of the method that have the GCD blocks wrapping calls to the interal methods. This doesn't quite feel right to me.
Here are a few thoughts:
See if you can't use immutable objects. This means that whenever a method would modify the object it actually returns a new object with the modified state. The blocks would then go on and use this new object. This is simple, requires no special care but is not always possible.
See if your public methods can't use private methods that carry around state. Since each block would carry around its own internal state then you are also thread safe.
If you had some example use case it might lead to a more ideas...
I've used a pattern like this very successfully in our C++ classes that use dispatch queues for synchronization:
class Foo
{
public:
void doSomething() {
dispatch_sync(fQueue, ^{ doSomething_sync(); });
}
private:
void doSomething_sync() { ... }
private:
dispatch_queue_t fQueue;
};
The general convention here is that for any given _sync method in a class, you only call other _sync methods and not their non _sync public counterpart.
Related
for example in the case:
#NSManaged public var myProperty: SomeType
func someFunc() {
concurrentNSManagedObjectContext.perform {
doSomething(with: self.myProperty)
}
}
and what is the best practices, if yes?
Using #NSManaged has no effect on thread safety. It helps Core Data manage the property but doesn't do anything about keeping the property safe for threads or anything else.
Using perform as you are is good if the doSomething function relates to Core Data, because perform and performAndWait are how Core Data manages thread safety. Accessing the property inside perform or performAndWait is safe; accessing it outside of those functions is usually not safe.
The only exception to the above is that if your managed object context uses main-queue concurrency (for example if you're using NSPersistentContainer and the context is the viewContext property) and you're sure that your code is running on the main queue, then you don't need to use perform or performAndWait. It's not bad to use them in that case but it's not necessary either.
"Thread safety" at least in Apple Platforms thus far resolves to two things; reading, and writing. NSManaged object currently does not protect against a mix of the two. func doSomething(...) is going to throw an exception if some other thread is reading myProperty at time of mutation. Mutation can be done on a serial thread, however thread safety is more complicated than that. someFunc() is called by the first caller; if that caller is coming from a concurrent thread there is no guarantee of the order. If for example myProperty is of type Int and I call someFunc concurrent from 200 threads, the last thread may be 0 and someFunc may be += 1. Now if I make the func serial my end output is 1. So the short answer is it depends on what you're trying to accomplish. generally you are safe on a serial queue, but concurrent takes a lot of planning.
I am learning objective c and swift. i didn't get what is difference between block and method or function in Objective c or in Swift.
int mutiplier=10;
int (^myBlock)(void)=^{
return 10 *3;
};
NSLog(#"%d",myBlock());
Or can write method/function like this
-(int)function:(int)num{
return num* 10;
}
Blockquote
Short and simple:
Block of code - just a block of code. You can declare it, define types of blocks(then make an instances), call blocks one by one, etc. Blocks can take parameters, can return something, It`s quite convenient to use them along with a Grand Central Dispatch. Blocks can declared right in the middle of the code, as an instance variable or as a property. They can also be passed as an arguments to a method/function call. After block has done its work you can call the 'completion' part to run some specific code, which is convenient in some cases. In a swift language similar to blocks (but not equal) thing is a closure. Would like to add that there is a block-based enumeration approach available in Objective-c which is almost as fast as Fast enumeration. Would recommend fast enumeration for most cases, but sometimes (rare) block enumeration is better. Other loops usually is not as fast as this two ones. One more important thing we should keep in mind is that the blocks are Objective-C objects while functions and methods are not. Blocks can capture values from the variables from the enclosing scope while to get the same values inside of a function/method you need to pass these variables as an arguments. Using blocks you can even change these variables using f.e.
__block int anInteger = 123;
syntax before the block call.
Keep in mind you avoid strong reference to a self when capturing it inside of a block to avoid retain cycles. Use weakSelf in that case.
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html
Function should have name, return something or be void.
Method is a function of a class.
Blocks are a way of wrapping up a piece of code and effectively storing it for later use. A block is commonly used in place of a call back function. Newer APIs in the iPhone SDK use blocks this way. The API will take a "block" of code that it will run on completion. And Blocks are presented in swift as a Closure.
In swift it's little tough syntax to learn closure. but trust me it's very handy way when you start to use it.
It saves you having to create your own threads and maintain the state of each thread, manage locks, setup autorelease pools etc.
Also, when used with the Grand Central Dispatch (GCD) API blocks can be run on queues and entire portions of code can be made to run asynchronously with very little effort, but still keeping the robustness that is required for multithreaded code.
I just created a singleton method, and I would like to know what the function #synchronized() does, as I use it frequently, but do not know the meaning.
It declares a critical section around the code block. In multithreaded code, #synchronized guarantees that only one thread can be executing that code in the block at any given time.
If you aren't aware of what it does, then your application probably isn't multithreaded, and you probably don't need to use it (especially if the singleton itself isn't thread-safe).
Edit: Adding some more information that wasn't in the original answer from 2011.
The #synchronized directive prevents multiple threads from entering any region of code that is protected by a #synchronized directive referring to the same object. The object passed to the #synchronized directive is the object that is used as the "lock." Two threads can be in the same protected region of code if a different object is used as the lock, and you can also guard two completely different regions of code using the same object as the lock.
Also, if you happen to pass nil as the lock object, no lock will be taken at all.
From the Apple documentation here and here:
The #synchronized directive is a
convenient way to create mutex locks
on the fly in Objective-C code. The
#synchronized directive does what any
other mutex lock would do—it prevents
different threads from acquiring the
same lock at the same time.
The documentation provides a wealth of information on this subject. It's worth taking the time to read through it, especially given that you've been using it without knowing what it's doing.
The #synchronized directive is a convenient way to create mutex locks on the fly in Objective-C code.
The #synchronized directive does what any other mutex lock would do—it prevents different threads from acquiring the same lock at the same time.
Syntax:
#synchronized(key)
{
// thread-safe code
}
Example:
-(void)AppendExisting:(NSString*)val
{
#synchronized (oldValue) {
[oldValue stringByAppendingFormat:#"-%#",val];
}
}
Now the above code is perfectly thread safe..Now Multiple threads can change the value.
The above is just an obscure example...
#synchronized block automatically handles locking and unlocking for you. #synchronize
you have an implicit lock associated with the object you are using to synchronize. Here is very informative discussion on this topic please follow How does #synchronized lock/unlock in Objective-C?
Excellent answer here:
Help understanding class method returning singleton
with further explanation of the process of creating a singleton.
#synchronized is thread safe mechanism. Piece of code written inside this function becomes the part of critical section, to which only one thread can execute at a time.
#synchronize applies the lock implicitly whereas NSLock applies it explicitly.
It only assures the thread safety, not guarantees that. What I mean is you hire an expert driver for you car, still it doesn't guarantees car wont meet an accident. However probability remains the slightest.
I've found an Objective-C SocketIO library and am trying to implement it in my first Swift app. Here's the code I'm trying to port:
__weak typeof(self) weakSelf = self;
self.socket.onConnect = ^()
{
weakSelf.socketIsConnected = YES;
[weakSelf mapView: weakSelf.mapView didUpdateUserLocation: weakSelf.mapView.userLocation];
};
From my limited understanding ^() {} is a block in Objective C. I've looked into it and closures seem to be a loose equivalent Swift. My first obvious question is how do I get the same result in Swift?
I've tried the following but get the error fatal error: unexpectedly found nil while unwrapping an Optional value (lldb):
self.socket.onConnect = { () -> Void in
println("Connected!")
}
Also, behind the scenes what's happening here? An asynchronous callback function would seem appropriate but wasn't used and I'd like to understand why.
UPDATE
As pointed out by #jtbandes, socket was in fact Nil as this code was running outside of the connection callback (I know, a very silly mistake). Solution to first question:
SIOSocket.socketWithHost(server) { (socket: SIOSocket!) in
self.socket = socket
self.socket.onConnect = { () -> Void in
println("Connected!")
}
}
Objective-C blocks and Swift closures are more than loose equivalents. They are direct equivalents.
A block/closure is an anonymous function that inherits it's enclosing scope.
I'm still working in Objective-C, so I'm used to its terminology. I'll use those terms
Blocks are useful in lots of ways.
Completion code is one example.
Without blocks, if you're setting up an async networking class, you might give it a delegate property, and define a protocol with callbacks that the class uses to notify it's delegate about events like download complete, errors, etc.
This makes for a lot of message handling infrastructure in lots of different places. You have to define a protocol. You have to add a delegate property to the networking class. You have to implement a set of delegate messages in the client class. You may have to pass context information to the callbacks, etc.
With blocks, you invoke a method that asks for a networking service, and provide a completion block. When the service is complete, it invokes the provided code block. You might add parameters to the completion block like a pointer to the data, a success boolean, or whatever is appropriate. The code block can have access to all the variables defined in its enclosing scope, which can be very helpful.
You can also save blocks into collections, you can use blocks in sort methods, and int lots of other cases.
The code you posted simply sets a block property on the object in question, self.socket. It looks like it is a block of code that gets called after a socket connection is established.
There are direct equivalents to this in Swift. I've only poked around in Swift however, so I'll leave it to others to help you with the translation.
I suggest browsing through Apple's classes for ideas on how to use blocks. Take a look at NSURLConnection and NSURLSession if you're interested in async networking. Take a look at the block-based view animation methods that take an animation block and a completion block. Those will give you an idea of the ways you can use blocks for handling async events, or passing code to a class to get work done.
Another interesting use of blocks is in handling collections like arrays. There are methods that take an NSComparator block and sort an array, and there are methods that will enumerate through an array, performing a block of code on each element and/or selecting a subset of the elements and returning an index set of the array indexes.
Duncan
What are the disadvantages of using a block to define a private method within a method, instead of using a real private method? Is there any apart from not being able to call the method from somewhere else?
Example:
-(NSDictionary*)serialize
{
NSMutableDictionary* serialization = [NSMutableDictionary dictionary];
TwoArgumentsBlockType serializeItemBlock = ^void(MyItemClass* item, NSString* identifier)
{
if (item)
{
// serialization code
}
};
serializeItemBlock(self.someItem1, kSomeIdentifier1);
serializeItemBlock(self.someItem2, kSomeIdentifier2);
serializeItemBlock(self.someItem3, kSomeIdentifier3);
serializeItemBlock(self.someItem4, kSomeIdentifier4);
serializeItemBlock(self.someItem5, kSomeIdentifier5);
serializeItemBlock(self.someItem6, kSomeIdentifier6);
serializeItemBlock(self.someItem7, kSomeIdentifier7);
serializeItemBlock(self.someItem8, kSomeIdentifier8);
serializeItemBlock(self.someItem9, kSomeIdentifier9);
serializeItemBlock(self.someItem10, kSomeIdentifier10);
serializeItemBlock(self.someItem11, kSomeIdentifier11);
return serialization;
}
I think the 3 biggest drawbacks are:
The block isn't reusable, as you mention.
The block isn't testable--you can't write a unit test that verifies the block does what you think it does.
The code is less readable. When you're reading this method, what's important is that a series of things are serialized, not the details of how the serialization is implemented.
Moving this block into a method would resolve all of these issues. If the block is used by some API that takes a block callback as an argument, you can always return the block from a method.
Clarity of the code is important.
Methods allow you to encapsulate entire sections of code apart from each other, and can make it easier to read..
Another reason to choose private methods over blocks is memory management. This is far to big of a topic to discuss here, but sufficed to say that blocks are weird in the memory management, and don't act like any other code structure in that regard.
Arguably it's harder to navigate the code - you tend to have entry points buried rather obscurely in the middle of some function, and there's no function name you can see in the debugger or search for, which can make debugging and tracing a little harder.