-
Notifications
You must be signed in to change notification settings - Fork 0
Objective C Basic Interview Questions?
-
strong, weak, assign property attributes define how memory for that property will be managed.
-
Strong means that the reference count will be increased and the reference to it will be maintained through the life of the object
-
Weak, means that we are pointing to an object but not increasing its reference count. It’s often used when creating a parent child relationship. The parent has a strong reference to the child but the child only has a weak reference to the parent.
-
Read only, we can set the property initially but then it can’t be changed.
-
Copy, means that we’re copying the value of the object when it’s created. Also prevents its value from changing.
synthesize generates getter and setter methods for your property. if we declare property synthesize we do not need to use - _ (underscore) and self. for using variable.
- The bounds of an UIView is the rectangle, expressed as a location (x,y) and size (width,height) relative to its own coordinate system (0,0).
- The frame of an UIView is the rectangle, expressed as a location (x,y) and size (width,height) relative to the superview it is contained within.
synchronized guarantees that only one thread can be executing that code in the block at any given time.
- SDWebImage
- NMRangeSlider
- MFSlideMenu
- QREncoder
- Reachability
- AFNetworking
- SwiftyJSON
- Mantle
- ObjectMapper
atomic (default)
- Atomic is the default: if you don’t type anything, your property is atomic. An atomic property is guaranteed that if you try to read from it, you will get back a valid value. It does not make any guarantees about what that value might be, but you will get back good data, not just junk memory. What this allows you to do is if you have multiple threads or multiple processes pointing at a single variable, one thread can read and another thread can write. If they hit at the same time, the reader thread is guaranteed to get one of the two values: either before the change or after the change. What atomic does not give you is any sort of guarantee about which of those values you might get. Atomic is really commonly confused with being thread-safe, and that is not correct. You need to guarantee your thread safety other ways. However, atomic will guarantee that if you try to read, you get back some kind of value.
nonatomic On the flip side, non-atomic, as you can probably guess, just means, “don’t do that atomic stuff.” What you lose is that guarantee that you always get back something. If you try to read in the middle of a write, you could get back garbage data. But, on the other hand, you go a little bit faster. Because atomic properties have to do some magic to guarantee that you will get back a value, they are a bit slower. If it is a property that you are accessing a lot, you may want to drop down to nonatomic to make sure that you are not incurring that speed penalty.
The second category of property attributes you can have are ones that modify access. There are also two in this class: readonly and readwrite (with self-explanatory titles).
readonly readonly makes it so this property is read-only. There is no setter for it at all. One caveat is that it cannot be readonly to everyone else, but readwrite to me: if you say readonly, it is read-only to everybody, including you.
readwrite (default) On the flip side, there is readwrite, which, of course, allows both read and write. That is the default; again, if you do not write anything, you have a readwrite property.
What if you want one property that works as readwrite to you, but readonly to everybody else? In your interface file you would declare it as readonly, but in your implementation file, you would create a class extension and redefine it as readwrite. The keyword in the interface communicates to others that they cannot write to (a.k.a., change) the property. However, the class extension at the top of your implementation (.m) file will redefine the property with the same name, only as readwrite instead, allowing you to write to the property within the implementation file.
The third category of property attributes is one that affects the way that your property stores its value. All properties are backed by instance variables, and in old-school Objective-C, you had to do all that yourself. You had to create the instance variable, and make sure they stayed in sync through getter and setter methods. Apple eventually introduced the @synthesize directive which would generate all that stuff for you, but they have since made that automatic for every variable. Now you just declare a property and it magically has a getter, a setter, and a backing variable that actually manages the value. However, if you want to tweak the way that that relationship works, there are four options for storage modifiers.
strong (default) The default is called strong. Strong just means you have a reference to an object and you will keep that object alive. As long as you hold that reference to the object in that property, that object will not be deallocated and released back into memory.
weak Strong’s analog is weak. Weak gives you a reference so you can still “talk” to that object, but you are not keeping it alive. If everyone else’s strong references go away, then that object is released. The nice thing about weak references is that they will automatically nil references that go away. If you have a reference to an object and all of the strong references to it go away and it gets deallocated, your weak reference does not point to some junk memory, which can give you crashes. It will just automatically nil itself out. Then, in Objective-C, you can safely send messages to nil and nothing happens. (You may want to handle that, of course, in some other way.) weak references are really common in delegate patterns (delegation essentially requires a weak reference to the delegate object).
The two storage attributes that you may not be quite as used to seeing are called assign and copy.
assign assign is the keyword used for primitives. It is pretty easy to understand: If you do not have an object, you cannot use strong, because strong tells the compiler how to work with pointers. But if you have a primitive (i.e. int, float, bool, or something without the little asterisk after the type), then you use assign, and that makes it work with primitives.
copy Lastly, there’s a keyword called copy. Copy I have seen most commonly with strings. It works really well with all kinds of mutable objects. If you set a copy property, instead of just setting both references to the same object, what it actually does is it makes a copy of the object you are setting and then sets the property to that copy. If I write in a string, it just copies that string so there are now two copies of that string. It leaves mine with me at the variable I passed in and just saves the copy. That way I can keep going with my string and I can modify it, and the one that I set remains the way that it was when I set it.
NSURLSession
- AFURLSessionManager
- AFHTTPSessionManager
-
AFSecurityPolicy
-
AFNetworkReachabilityManager
-
AFURLSessionManager creates and manages an NSURLSession object based on a specified NSURLSessionConfiguration object, which conforms to , , , and .
Request Serialization
Request serializers create requests from URL strings, encoding parameters as either a query string or HTTP body.
Network Reachability Manager
AFNetworkReachabilityManager monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces.
- Do not use Reachability to determine if the original request should be sent.
- You can use Reachability to determine when a request should be automatically retried.
- Network reachability is a useful tool for determining why a request might have failed.
Security Policy
- AFSecurityPolicy evaluates server trust against pinned X.509 certificates and public keys over secure connections.
- Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities.
- Add a new file to Xcode (File > New > File), then select “Source” and click “Header File“.
- Name your file “YourProjectName-Bridging-Header.h”. Example: In my app Station, the file is named “Station-Bridging-Header”.
- Create the file.
- Navigate to your project build settings and find the “Swift Compiler – Code Generation” section. You may find it faster to type in “Swift Compiler” into the search box to narrow down the results. Note: If you don’t have a “Swift Compiler – Code Generation” section, this means you probably don’t have any Swift classes added to your project yet. Add a Swift file, then try again.
- Next to “Objective-C Bridging Header” you will need to add the name/path of your header file. If your file resides in your project’s root folder simply put the name of the header file there. Examples: “ProjectName/ProjectName-Bridging-Header.h” or simply “ProjectName-Bridging-Header.h”.
- Open up your newly created bridging header and import your Objective-C classes using #import statements. Any class listed in this file will be able to be accessed from your swift classes.
NSString *pathToCert = [[NSBundle mainBundle]pathForResource:@"github.com" ofType:@"cer"];
NSData *localCertificate = [NSData dataWithContentsOfFile:pathToCert];
manager.securityPolicy.pinnedCertificates = @[localCertificate];
-
Blocks are an Apple extension to the Objective-C language that were motivated by the desire to pass small pieces of code in API calls to the Grand Central Dispatch multithreading system. Grand Central Dispatch works by making use of queues containing such small pieces of code, each representing a task or unit of work to be done. Blocks have been available in iOS since version 4.
-
The basic idea of a block is to treat a small piece of code as if it were a value. The piece of code can then be passed as a parameter in messages or assigned to a variable. Eventually, at some future time, the code will be executed.
-
The most basic form of a block, known as a "block literal", consists of a caret character ("^"), followed by a set of curly braces that contain the actual code, as shown below: ^{ NSLog(@"Hi, I'm a block literal.");
}
-
SDWebImage library, that has a lot of features for working with images, including getting them asynchronously. However, if you’re just looking for that one functionality, there is a simple way to handle image downloads by first creating this method:
- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, UIImage *image))completionBlock
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
UIImage *image = [[UIImage alloc] initWithData:data];
completionBlock(YES,image);
} else{
completionBlock(NO,nil);
}
}];
} -
Basically, you send in a URL (or you can modify the method to send in a url string if you want) and a completion block, and do a normal asynchronous url request to the image url. You know that the data that will be returned will be an image, which you instantiate, and pass in to the passed in completion block.
-
Now, in my tableView:cellForRowAtIndexPath: method, I can download the image and save it asynchronously:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"venue";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
`if (!cell) {` <br>
`cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];` <br>
`}` <br>
`Venue *venue = ((Venue * )self.venues[indexPath.row]);` <br>
`if (venue.userImage) {` <br>
`cell.imageView.image = venue.image;` <br>
`} else {` <br>
`// set default user image while image is being downloaded` <br>
`cell.imageView.image = [UIImage imageNamed:@"batman.png"];` <br>
`// download the image asynchronously`
`[self downloadImageWithURL:venue.url completionBlock:^(BOOL succeeded, UIImage *image) {` <br>
`if (succeeded) {` <br>
`// change the image in the cell` <br>
`cell.imageView.image = image;` <br>
`// cache the image for use later (when scrolling up)`
`venue.image = image;` <br>
`}` <br>
`}];` <br>
`}` <br>
}
-
A memory leak occurs when a given memory space cannot be recovered by the system because it is unable to tell if this memory space is actually in use or not.
-
One of the most common problems that generate memory leaks in iOS is retain cycles. This occurs when we make circular references between two or more objects. A retain cycle prevents that the memory used by these objects be released even if the creator of these objects release them.
- There are four important parts of the NSNotificationCenter method addObserver:selector:name:object: . The argument for addObserver: is the object that wants to know when a certain notification happens. The argument for selector: is the method that gets called when the notification happens.
- NSNotification objects encapsulate information so that it can be broadcast to other objects by an NSNotificationCenter object. An NSNotification object (referred to as a notification) contains a name, an object, and an optional dictionary. The name is a tag identifying the notification.
Whereas completion handler is a way (technique) for implementing callback functionality using blocks. A completion handler is nothing more than a simple block declaration passed as a parameter to a method that needs to make a callback at a later time App Extensions Increase Your Impact An app extension lets you extend custom functionality and content beyond your app and make it available to users while they’re interacting with other apps or the system.
- You create an app extension to enable a specific task. For example, to let users post to your social service from a web browser, you can provide a Share extension. Or, to let users catch up on their favorite team, you can provide a Today widget that displays current sports scores in Notification Center. You can even create an app extension that provides a custom keyboard that users can use in place of the iOS system keyboard.
