Should I check [NSApplication sharedApplication] for a nil return? - objective-c

In a MacOS app in Objective-C is it possible for [NSApplication sharedApplication] to return nil or is it a safe assumption that this will never return nil?
The Documentation describes the behavior:
Returns the application instance, creating it if it doesn’t exist yet.
However:
Is there any possibility to fail to create it? For example if the memory for the NSApplication object cannot be allocated?
If such an unexpected error prevents the object from being created would the framework automatically detect this and crash instead of returning nil?
Would the following if statement serve any purpose?
#import <Cocoa/Cocoa.h>
int main() {
if (![NSApplication sharedApplication]) {
return -1;
}
// ...
[NSApp run];
}
My goal is to write absolutely correct code, not just good enough in almost all cases, while remaining as concise as possible.

sharedApplication is of _Nonnull as the code says and as the documentation seys:
Summary:
Returns the application instance, creating it if it doesn’t exist yet.
Source: sharedApplication

Related

Objective-C method parameter type-safety

If I have methods like:
- (BOOL)isValidRow:(NSDictionary*)contentVersionRow
do we really have to continually check like this at the beginning of the method
if(![contentVersionRow isKindOfClass:[NSDictionary class]]) {
// Handle unusual situation - probably return NO in this case
}
to really implement proper type-safety inside Objective-C methods? Because in theory the parameter is not guaranteed to point to an NSDictionary object, is this correct?
EDIT: So answers so far seem to indicate we should not check for this, but then what is the difference between checking for this and checking for nil parameter, which I assume we should do? Or should we not check for nil either, if it's not normally expected? Both cases cover the situation of a misbehaving caller.
Just like in C you are dealing with pointers in Objective-C. So saying NSDictionary * simply means "here's a pointer to a memory address that contains an instance of NSDictionary".
Example:
#import <Foundation/Foundation.h>
#interface Test : NSObject
- (void)useDictionary:(NSDictionary *)dictionary;
#end
#implementation Test
- (void)useDictionary:(NSDictionary *)dictionary
{
NSLog(#"Keys: %#", [dictionary allKeys]);
}
#end
int main(int argc, char *argv[]) {
#autoreleasepool {
Test *test = [[Test alloc] init];
// 1: This works fine
[test useDictionary:#{#"key": #"value"}];
// 2: This will cause a compiler warning (or error depending on the options passed to the compiler)
[test useDictionary:#"not a dictionary"];
// 3: This will compile without any warnings
[test useDictionary:(NSDictionary *)#"not a dictionary"];
}
}
The 2nd and 3rd examples will cause the program to crash at runtime. So if you want to pass incorrect things to methods, you can. Usually Xcode will warn you if you have a type-mismatch.
Update about nil-checking: If it's an API-misuse to pass nil to your method, then throw an exception. That's what exceptions are for in Objective-C: to catch programming mistakes, not to handle expected runtime issues (like an unreachable network). If your method can just silently fail if nil is passed in or handle it in a sensible way, then do that instead. For example if you have a method addValue:(NSNumber *)number that adds the given value to a sum then it wouldn't be a big deal if someone called it with nil: Just don't add anything :)
Yes, but you shouldn’t.
Obj-C is a dynamic language, so it is up to each object to determine if it responds to a certain method. It is bad style to check the class of an object.
Instead, if you want to check that an object supports a selector you should use -respondsToSelector:, but only if you handle objects not responding to that selector.

ObjectiveC and JavaScriptCore: Will using this method of calling CallBacks cause memory issues?

DISCLAIMER: This is a long post, but could prove very valuable for those grappling with using the new ObjectiveC JavascriptCore framework and doing asynchronous coding between ObjC and JS.
Hi there, I'm super new to Objective C and am integrating a javascript communication library into my iOS app.
Anyway, I've been trying my hand at using the new ObjectiveC JavaScriptCore Framework introduced in iOS7. It's pretty awesome for the most part, though quite poorly documented so far.
It's really strange mixing language conventions, but also kind of liberating in some ways.
I should add that I am of course using ARC, so that helps a lot coming from the Javascript world. But I have a question that's pretty specific around memory use issues when moving between ObjectiveC and the JSContext callBacks. Like if I execute a function in Javascript that then does some asynchronous code, and then calls back to a defined ObjectiveC block, and then that calls a defined JS callback... I just want to make sure I'm doing it right (ie. not leaking memory some place)!
Just to do things proper (because I reference a the class self to call the ObjectiveC callBacks I create a weakSelf so it plays nice with ARC (referenced from question: capturing self strongly in this block is likely to lead to a retain cycle):
__unsafe_unretained typeof(self) weakSelf = self;
Now, say I have a JSContext and add a function to it. I want this function to take a callBack function and call it with "Hello" as an argument as well as pass ANOTHER function as a callBack. ie.
// Add a new JSContext.
JSContext context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]];
// Add a function to the context. This function takes a callBack function and calls it back with "Hello"
[context evaluateScript: #"var functionA = function(callBack){
var aMessage = "Foo";
callBack(aMessage, function(message){
/* message should say: Foo Bar */
});
}" ];
// Note, if you try to copy this code, you will have to get rid of the returns in the JS script.
Okay, so we have our basic JS side of things. Now to add the ObjectiveC complexity. I'm going to add the first ObjectiveC CallBack block:
context[#"functionB"] = ^(NSString *theMessage, JSValue *theCallBack){
[weakSelf objCFunction:theMessage withCallBack:theCallBack];
};
In the same class all this is happening in I also have the method definition. This is the place that causes the most concern to me:
-(void)objCFunction:(NSString *)message withCallBack:(JSValue *)callBack
{
NSString *concatenatedString = [NSString stringWithFormat:#"%#%#", message, #"Bar"];
[callBack callWithArguments:#[concatenatedString]];
}
So when I call:
[context evaluateScript: #"functionA(functionB);" ];
It should pass through the chain, and it does exactly what I expect it to do.
My main concern is that I hope I'm not somehow capturing a JSValue somewhere along this chain that is then leaking out.
Any help in helping me understand how ARC/the JSMachine would manage this approach to calling callBacks fluidly between Objective C and Javascript, would be super valuable!
Also, I hope this question helps others out there who are experimenting with this framework.
Thanks!
The problem with retain cycles occurs when you have two objects, each of which retains part of another. It's not specific to JavascriptCore. It's not even specific to blocks although blocks make the problem much easier to blunder into.
E.g.
#interface ObjcClass : NSObject
#property (strong,nonatomic) JSValue *badProp;
- (void) makeEvilRetainWithContext:(JSContext *) context;
#end
- (void) makeEvilRetainWithContext:(JSContext *) context{
context[#"aFunc"]=^(JSValue *jsValue){
self.badProp=jsValue;
};
}
The self.context[#"aFunc"] now retains the ObjcClass object because self.badProp is now inside the function obj inside the context created by assigning the block to #"aFunc". Likewise, the context is retained because one of its own strongly retained values is retained in self.badProp.
Really, the best way to avoid all this is just to not try and store JSValue in objective-c objects ever. There really doesn't seem to be a need to do so e.g.
#property (strong,nonatomic) NSString *goodProp;
- (void) makeGoodFunc:(JSContext *) context;
#end
- (void) makeGoodFunc:(JSContext *) context{
context[#"aFunc"]=^(JSValue *jsValue){
self.goodProp=[JSValue toString];
};
}
You code isn't a problem because simply passing a JSValue (even a function) through a method won't retain it.
Another way to think of it might be: After, objCFunction:withCallBack: executes, would there be anyway for the object represented by self to access the JSValue passed as callBack? If not, then no retain cycle.
Check out the WWDC introduction "Integrating JavaScript into Native Apps" session on Apple's developer network: https://developer.apple.com/wwdc/videos/?id=615 - it contains a section on Blocks and avoiding capturing JSValue and JSContext
In your sample code above, all the JSValues are passed as arguments (the way Apple recommends) so the references only exist whilst the code is executed (no JSValue objects are captured).

Objective-C remove all oberservers for a certain notification

I have an iPad app that uses a proprietary library object which registers for a "UIScreenDidConnectNotification". Occasionally this object is deallocated and reallocated behind the scenes. As it is in a library, I cannot ensure that it is properly removing this observer.
Is there a way for me to manually remove all/any observers for a specific notification (i.e. UIScreenDidConnectNotification) without having any access to the object that has registered. This would keep the application from sending the message to a deallocated object.
Update: Here is the easiest way to fix my problem. I wish I could do a better job, but life is too short.
#import
#import
#interface NSNotificationCenter (AllObservers)
#end
#implementation NSNotificationCenter (AllObservers)
// This function runs before main to swap in our special version of addObserver
+ (void) load
{
Method original, swizzled;
original = class_getInstanceMethod(self, #selector(addObserver:selector:name:object:));
swizzled = class_getInstanceMethod(self, #selector(swizzled_addObserver:selector:name:object:));
method_exchangeImplementations(original, swizzled);
// This function runs before main to swap in our special version of addObserver
+ (void) load
{
Method original, swizzled;
original = class_getInstanceMethod(self, #selector(addObserver:selector:name:object:));
swizzled = class_getInstanceMethod(self, #selector(swizzled_addObserver:selector:name:object:));
method_exchangeImplementations(original, swizzled);
}
/*
Use this function to remove any unwieldy behavior for adding observers
*/
- (void) swizzled_addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(id)notificationSender
{
NSString *notification = [[NSString alloc] initWithUTF8String: "UIScreenDidConnectNotification" ];
// It's a hack, but I just won't allow my app to add this type of notificiation
if([notificationName isEqualToString: notification])
{
printf("### screen notifcation added for an observer: %s\n", [notificationSender UTF8String] );
}
else
{
// Calls the original addObserver function
[self swizzled_addObserver:notificationObserver selector:notificationSelector name:notificationName object:notificationSender];
}
}
As it is in a library, I cannot ensure that it is properly removing this observer.
If the object is created in a library, it's not your responsibility to remove the object. If the library is deallocating the object without removing it from the notification center, that's a clear bug in the library.
Is there a way for me to manually remove all/any observers for a specific notification... without having any access to the object that has registered.
There's nothing in the API for NSNotificationCenter that lets you do that. Just the opposite, in fact -- the methods that let you remove the observer all require a pointer to a specific object.
I agree with both of Caleb's points: it is not your responsibility to perform this task and there is nothing in the API to support it.
However... if you feel like hacking something in to perform this task for whatever reason, refer to this thread: How to retrieve all NSNotificationCenter observers?
The selected answer of that thread has a category for NSNotificationCenter that allows you to retrieve all observers for a given notification name. Again, this is not recommended though.

Objective-C & KeyValueCoding: How to avoid an exception with valueForKeyPath:?

I've got an object of type id and would like to know if it contains a value for a given keyPath:
[myObject valueForKeyPath:myKeyPath];
Now, I wrap it into a #try{ } #catch{} block to avoid exceptions when the given keypath isn't found. Is there a nicer way to do this? Check if the given keypath exists without handling exceptions?
Thanks a lot,
Stefan
You could try this:
if ([myObject respondsToSelector:NSSelectorFromString(myKeyPath)])
{
}
However, that may not correspond to the getter you have, especially if it is a boolean value. If this doesn't work for you, let me know and I'll write you up something using reflection.
For NSManagedObjects, an easy solution is to look at the object's entity description and see if there's an attribute with that key name. If there is, you can also take it to the next step and see what type of an attribute the value is.
Here's a simple method that given any NSManagedObject and any NSString as a key, will always return an NSString:
- (NSString *)valueOfItem:(NSManagedObject *)item asStringForKey:(NSString *)key {
NSEntityDescription *entity = [item entity];
NSDictionary *attributesByName = [entity attributesByName];
NSAttributeDescription *attribute = attributesByName[key];
if (!attribute) {
return #"---No Such Attribute Key---";
}
else if ([attribute attributeType] == NSUndefinedAttributeType) {
return #"---Undefined Attribute Type---";
}
else if ([attribute attributeType] == NSStringAttributeType) {
// return NSStrings as they are
return [item valueForKey:key];
}
else if ([attribute attributeType] < NSDateAttributeType) {
// this will be all of the NSNumber types
// return them as strings
return [[item valueForKey:key] stringValue];
}
// add more "else if" cases as desired for other types
else {
return #"---Unacceptable Attribute Type---";
}
}
If the key is invalid or the value can't be made into a string, the method returns an NSString error message (change those blocks to do whatever you want for those cases).
All of the NSNumber attribute types are returned as their stringValue representations. To handle other attribute types (e.g.: dates), simply add additional "else if" blocks. (see NSAttributeDescription Class Reference for more information).
If the object is a custom class of yours, you could override valueForUndefinedKey: on your object, to define what is returned when a keypath doesn't exist.
It should be possible to graft this behavior onto arbitrary classes reasonably simply. I present with confidence, but without warranty, the following code which you should be able to use to add a non-exception-throwing implementation of valueForUndefinedKey: to any class, with one, centralized line of code per class at app startup time. If you wanted to save even more code, you could make all the classes you wanted to have this behavior inherit from a common subclass of NSManagedObject and then apply this to that common class and all your subclasses would inherit the behavior. More details after, but here's the code:
Header (NSObject+ValueForUndefinedKeyAdding.h):
#interface NSObject (ValueForUndefinedKeyAdding)
+ (void)addCustomValueForUndefinedKeyImplementation: (IMP)handler;
#end
Implementation (NSObject+ValueForUndefinedKeyAdding.m):
#import "NSObject+ValueForUndefinedKeyAdding.h"
#import <objc/runtime.h>
#import <objc/message.h>
#implementation NSObject (ValueForUndefinedKeyAdding)
+ (void)addCustomValueForUndefinedKeyImplementation: (IMP)handler
{
Class clazz = self;
if (clazz == nil)
return;
if (clazz == [NSObject class] || clazz == [NSManagedObject class])
{
NSLog(#"Don't try to do this to %#; Really.", NSStringFromClass(clazz));
return;
}
SEL vfuk = #selector(valueForUndefinedKey:);
#synchronized([NSObject class])
{
Method nsoMethod = class_getInstanceMethod([NSObject class], vfuk);
Method nsmoMethod = class_getInstanceMethod([NSManagedObject class], vfuk);
Method origMethod = class_getInstanceMethod(clazz, vfuk);
if (origMethod != nsoMethod && origMethod != nsmoMethod)
{
NSLog(#"%# already has a custom %# implementation. Replacing that would likely break stuff.",
NSStringFromClass(clazz), NSStringFromSelector(vfuk));
return;
}
if(!class_addMethod(clazz, vfuk, handler, method_getTypeEncoding(nsoMethod)))
{
NSLog(#"Could not add valueForUndefinedKey: method to class: %#", NSStringFromClass(clazz));
}
}
}
#end
Then, in your AppDelegate class (or really anywhere, but it probably makes sense to put it somewhere central, so you know where to find it when you want to add or remove classes from the list) put this code which adds this functionality to classes of your choosing at startup time:
#import "MyAppDelegate.h"
#import "NSObject+ValueForUndefinedKeyAdding.h"
#import "MyOtherClass1.h"
#import "MyOtherClass2.h"
#import "MyOtherClass3.h"
static id ExceptionlessVFUKIMP(id self, SEL cmd, NSString* inKey)
{
NSLog(#"Not throwing an exception for undefined key: %# on instance of %#", inKey, [self class]);
return nil;
}
#implementation MyAppDelegate
+ (void)initialize
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[MyOtherClass1 addCustomValueForUndefinedKeyImplementation: (IMP)ExceptionlessVFUKIMP];
[MyOtherClass2 addCustomValueForUndefinedKeyImplementation: (IMP)ExceptionlessVFUKIMP];
[MyOtherClass3 addCustomValueForUndefinedKeyImplementation: (IMP)ExceptionlessVFUKIMP];
});
}
// ... rest of app delegate class ...
#end
What I'm doing here is adding a custom implementation for valueForUndefinedKey: to the classes MyOtherClass1, 2 & 3. The example implementation I've provided just NSLogs and returns nil, but you can change the implementation to do whatever you want, by changing the code in ExceptionlessVFUKIMP. If you remove the NSLog, and just return nil, I suspect you'll get what you want, based on your question.
This code NEVER swizzles methods, it only adds one if it's not there. I've put in checks to prevent this from being used on classes that already have their own custom implementations of valueForUndefinedKey: because if someone put that method in their class, there's going to be an expectation that it will continue to get called. Also note that there may be AppKit code that EXPECTS the exceptions from the NSObject/NSManagedObject implementations to be thrown. (I don't know that for sure, but it's a possibility to consider.)
A few notes:
NSManagedObject provides a custom implementation for valueForUndefinedKey: Stepping through its assembly in the debugger, all it appears to do is throw roughly the same exception with a slightly different message. Based on that 5 minute debugger investigation, I feel like it ought to be safe to use this with NSManagedObject subclasses, but I'm not 100% sure -- there could be some behavior in there that I didn't catch. Beware.
Also, as it stands, if you use this approach, you don't have a good way to know if valueForKey: is returning nil because the keyPath is valid and the state happened to be nil, or if it's returning nil because the keyPath is invalid and the grafted-on handler returned nil. To do that, you'd need to do something different, and implementation specific. (Perhaps return [NSNull null] or some other sentinel value, or set some flag in thread-local storage that you could check, but at this point is it really all that much easier than #try/#catch?) Just something to be aware of.
This appears to work pretty well for me; Hope it's useful to you.
There's no easy way to solve this. Key Value Coding (KVC) isn't intended to be used that way.
One thing is for sure: using #try-#catch is really bad since you're very likely to leak memory etc. Exceptions in ObjC / iOS are not intended for normal program flow. They're also very expensive (both throwing and setting up the #try-#catch IIRC).
If you look at the Foundation/NSKeyValueCoding.h header, the comment / documentation for
- (id)valueForKey:(NSString *)key;
clearly states which methods need to be implemented for -valueForKey: to work. This may even use direct ivar access. You would have to check each one in the order described there. You need to take the key path, split it up based on . and check each part on each subsequent object. To access ivars, you need to use the ObjC runtime. Look at objc/runtime.h.
All of this is vary hacky, though. What you probably want is for your objects to implement some formal protocol and then check -conformsToProtocol: before calling.
Are your key paths random strings or are those strings under your control? What are you trying to achieve? Are you solving the wrong problem?
I don't believe this is possible in a safe way (i.e. without mucking with -valueForUndefinedKey: or something similar on other peoples' classes). I say that because on the Mac side of things, Cocoa Bindings—which can be set to substitute a default value for invalid key paths—simply catches the exceptions that result from bad key paths. If even Apple's engineers don't have a way to test if a key path is valid without trying it and catching the exception, I have to assume that such a way doesn't exist.

Why can't my singleton class return a value that will stay in scope

Stick with me. I'm visually impaired, have never used this site before, and will probably not post this in precisely the format that you are all used to. I apologize for any unintentional faux pas's herein.
Using Objective-C in an iOS project…
I have a singleton class, set up in what appears to be the usual way for Objective-C. It is, in the main, a series of methods which accept NSString values, interprets them, and return something else. In the code below, I'm simplifying things to the barest minimum, to emphasize the problem I am having.
From the singleton class:
- (NSUInteger) assignControlState:(NSString *)state {
// excerpted for clarity...
return UIControlStateNormal; // an example of what might be returned
}
Now, an instance of another class tries to use this method like so:
- (void) buttonSetup:(UIButton*)button {
[button setTitle:#"something" forState:[[SingletonClass accessToInstance] assignControlState:#"normal"]];
}
This code actually works. HOwever, when the system goes to draw the UI which includes the button whose title was set in this way, an EXC_BAD_ACCESS error occurs.
If the assignControlState method is moved into the same class as the buttonSetup method, no error is generated.
I'm guessing this is something about Apple's memory management that I'm not fully understanding, and how things go in and out of scope, but for the life of me, I can't figure out where I'm going wrong.
HOpe someone can help. Thanks.
The problem is in your accessToInstance method. I'll bet you are under-retaining. The implementation should be more like this:
static SingletonClass *sSingletonClass = nil;
#implementation
+ (id)accessToInstance {
if (sSingletonClass == nil) {
sSingletonClass = [[[self class] alloc] init];
}
return sSingletonClass;
}
#end
Now, if your program is following normal memory management rules, the singleton will stay around. You can check by writing:
- (void)dealloc {
[super dealloc]; // <-- set a breakpoint here.
}
If the debugger ever stops at this breakpoint, you know something in your program has over-released the singleton.
You know that bit you excerpted for clarity? I think you need to show us what it is because there's probably an over release in it somewhere.
Specifically, I think you release an autoreleased object. If you do that and don't use the object again, everything will carry on normally until the autorelease pool gets drained. The autorelease pool gets drained automatically at the end of the event at about the same time as the drawing normally occurs.
That would also explain the delayed crash following the NSLogs.