I’m new on objc/Cocoa and I never use C before.
I’ve a problem to get previously defined C struct data…
Here’s my code :
AppController.h
#import <Cocoa/Cocoa.h>
@interface AppController : NSObject {
AuthorizationRef authRef;
AuthorizationRights authRights;
AuthorizationFlags authFlags;
}
- (IBAction)toggleAuthentification:(id)sender;
@end
AppController.m
#import "AppController.h"
@implementation AppController
- (id)init {
if (![super init])
return nil;
AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authRef);
AuthorizationItem rightItems[1] = {{"com.myname.myapp.adminRights", 0, NULL, 0}};
authRights.count = 1;
authRights.items = rightItems;
authFlags = kAuthorizationFlagDefaults | kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize;
return self;
}
- (IBAction)toggleAuthentification:(id)sender {
NSLog(@"%d", AuthorizationCopyRights(authRef, &authRights, kAuthorizationEmptyEnvironment, authFlags ^ kAuthorizationFlagInteractionAllowed, NULL));
}
@end
When I click on a button in my app that call toggleAuthentification:, I get error code -60008 (errAuthorizationInternal).
In the debugger I can see authRights.count = 1, that correct, but authRights.items do not correspond in any way to data defined in init.
I try many different way but I don’t find solution.
Please, anyone can explain why it doesn’t work like I would it work and how to resolve my problem.
Bil
The problem in your code is memory management.
When you create
rightItems[], an array ofAuthorizationItemelements, it is created in the stack sincerightItems[]is an automatic (local) variable. This means that the memory used by the array is deallocated at the end of the method. Since you’re assigningrightItems[]toauthRights.items,authRights.itemspoints to a bogus memory address after-inithas finished executing. Any further reference toauthRights.itemshas undefined behaviour and is likely to produce an error in your program.What you need to do is to create the array in the heap so that it isn’t deallocated when
-inithas finished executing. You can do that viamalloc(). For instance:In theory, you’re responsible for releasing authRights.items when it’s not needed any longer since you’ve allocated memory for it in the heap. Hence, in your
-deallocmethod:I’ve said in theory because you’re storing the authorisation rights in your application controller. Since the application controller lives throughout the application lifecycle, technically it won’t receive
-releaseor-dealloc. However, it’s good practice and potentially useful in case you rearchitect your application and that code ends up being in a class whose objects are not necessarily alive until the application exits.One further note: you should assign the return value of
[super init]toselfin your-initmethod. This is also good practice since it is possible that[super init]returns a different object than currentself.