I saw a similar question addressing differences of the code completion between Xcode 3.2 and Xcode 4. My question addresses a specific behaviour of Xcode (3.2).
When I declare "private" methods in a class extension, these methods are visible in the code completion lists, where they shouldn't be visible.
An example (AClass.m):
#import "AClass.h"
#interface AClass()
- (void)someMethod;
#end
#implementation AClass
//...
- (void)someMethod
{
// do something here
}
//...
#end
When I import AClass.h to some other class and create an AClass-instance...
AClass *test = [[AClass alloc] init];
Xcode's code-completion shows the "private" method "someMethod":
[test som // Shows someMethod, though it shouldn't be visible here
At that point, this method is visible, even if it shouldn't be, because it's unknown here - it's not defined in the header-file. If I send the message [test someMethod] at that point and build the thing, I get a warning, that the object might not respond - as expected.
It actually does respond, but this is confusing behaviour, especially for someone else, who wants to use my class.
That affects #property / #synthesize as well, since they "just substitute methods". I want to access all of my private ivars by properties for a) having homogene code while b) being able to influence the use of ivars (like lazy instantiation). On the other hand all private stuff shouldn't be visible (in code completion) to anyone using my classes, to make it easier to use them.
Is there any way to change this behaviour?
Is the missing validation of context in Xcode 3.2 the reason, why code-completion shows this kind of methods, where they shouldn't be visible?
Is that behaviour different in Xcode 4 (because of context-validation)?
I still use Xcode 3.2, because I wanted to finish a project before switching and adapting myself to Xcode 4.
Related
I have an NSWindow which can be closed and reopened (I've called [setReleasedWhenClosed: NO]). How do I check if it is open or closed programmatically?
I've read the doc and Googled but can't see a sane way to do this. [isVisible] is deprecated. [occlusionState] isn't what I'm after. I've worked around it using notifications, but I can't believe there isn't some property or method on NSWindow to do this
-[NSWindow isVisible] is not really deprecated.
For the 10.10 SDK, Apple went through and converted a bunch of informal properties to declared properties. An informal property is one for which there are just accessors declared, possibly just a getter method. A declared property uses #property.
As a consequence, they removed something like:
- (BOOL) isVisible;
and added:
#property (getter=isVisible, readonly) BOOL visible;
Note that both still imply the existence of an -isVisible getter with BOOL return type.
The tools they use to generate the documentation from the changes to their headers caused the documentation to claim that -isVisible is deprecated, but that's just wrong.
Note, though, that -isVisible reports false for a window which is minimized or which is "open" but in a hidden app.
You make make of use of screen property of NSWindow. If the window in offscreen it will return nil. Please check https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindow_Class/index.html#//apple_ref/occ/instm/NSWindow/screen
I have a C function heightParameter that is a simple tool that I use in a couple of my UIViewControllers. I am declaring this only in my main implementation of each UIViewController subclass (in the .m) above my other functions, so that I didn't even have to declare it in the header.
For some reason, I'm getting duplicate symbols in every other subclass that I use it in, despite it being implemented privately. It is within the main #implementation #end block for each subclass and shouldn't be seen by anything else, so how is it being seen globally?
C function names have global scope. Mark it static or make it a method if you want it to be restricted.
a project which is iOS5 only and ARC enabled compiles on Xcode 4.3.1 beta. When compiling on 4.2.1. LLVM is throwing warnings like these:
"ARC forbids synthesizing a property of an Objective-C object with
unspecified ownership or storage attribute"
So the property definitions looks like this:
#property (nonatomic) NSObject* object
ARC is enabled in Build Settings. Adding a strong attribute fixes this warning but this should be default right?
Is there a difference between the Xcode versions in handling those property defaults?
Thanks
Andi
This is not beta specific Xcode 4.2.1 has the same behavior (betas are under NDA and should only legally be discussed in apple's developer forums):
Strong is the default setting for ivars. For ivars if you want __unsafe_unretained or __weak you must specify.
It has always been best practice to specify attributes in property declarations. One example that pops most quickly to mind is the UILabel property text, defined as:
#property(nonatomic,copy) NSString *text; // default is nil
In this example the copy attribute tells me I can pass an NSMutableString reference to the label and it will make a copy and I can go on mutating the string the label will remain the same. The behavior is clearly defined.
And I suspect it's the clearly defined behavior which was the most prominent reason that the ARC compiler forces you to specify storage attributes. Remember with the new runtimes eliminating the need to declare ivars for properties and #synthesize for accessor methods, it's conceivable that the property declaration is the only point you will notice if you accidentally retained a delegate.
Also consider the possibility that a few classes in a project may have been excluded from ARC in these cases there internal implementation would be completely opaque to ARC.
I have an ImageView which shows a lock, informing if an opened file is locked or not. I have 2 images for locked and unlocked cases. I want synchronize the displayed image with boolean value of my object representing an opened file.
To do this I want my ViewController to change the image in my ImageView depending on lock state of object. So both object and ViewController have a property "isLocked".
How can I synchronize them? It is easy in IB but I don't know how to do it programmatically. I tried in initialize method of my ViewController to use:
[ViewController bind:#"value" toObject:[ArrayController selection] withKeyPath:#"isLocked" options:nil];
But it doesn't work. In documentation it is said that I have to expose my binding before using it.
I try to put the following code in initializer method of my object:
[self exposeBinding:#"isLocked"];
But Xcode doesn't recognize this method.
Does somebody have experience with this kind of bindings establishing?
As #nick says, you want Key-Value-Observing.
[arrayController addObserver:self
forKeyPath:#"selection.isLocked"
options:NSKeyValueObservingOptionNew
context:#"this_context"]
Then when isLocked changes the -observeValueForKeyPath:ofObject:change:context: method that you have added to your viewController will be called (as long as you only manipulate isLocked in a KVC compliant way).
The options parameter lets you optionally tweak exactly what conditions will trigger the notification and what data is sent along with the notification. The context parameter is there to help you distinguish between notifications that you registered to receive and notifications your superclass registered to receive. It is optional.
Bindings seem like they might be useful to keep two values in sync. However, this is not what they do at all.
Yes, lots of things seem to give the impression that this is what they do, and there isn't much saying that this isn't what they do, also lots of people believe that this is what they do - but no, you cannot use them for this.
Only a handful of classes support bindings (they are listed here) and then, and this is the important bit, those classes only support binding their named bindings, and these bindings are not instance variables. eg NSTextField has a 'fontFamilyName' binding yet NSTextField does not have a 'fontFamilyName' property or instance variable, even a derived one. NSTextField does have a 'isBordered' property but not a binding - so you cannot bind 'isBordered'.
It does not mean anything to 'bind' an arbitrary property of an arbitrary Class.
Yes, you can bind two arbitrary values, the following code works just fine:
#import <Cocoa/Cocoa.h>
#interface SomeObject : NSObject
#property (retain,nonatomic) id someValue;
#end
#implementation SomeObject
#end
int main()
{
SomeObject *source=[SomeObject new];
SomeObject *target=[SomeObject new];
[target bind:#"someValue" toObject:source withKeyPath:#"someValue" options:0];
[source bind:#"someValue" toObject:target withKeyPath:#"someValue" options:0];
[source setSomeValue:#(42)];
NSLog(#"target: %#",[target someValue]);
[target setSomeValue:#(22)];
NSLog(#"source: %#",[source someValue]);
return 0;
}
As far as I can tell, the problem is the bit [ArrayController selection]. The first problem is that ArrayController is (or should be) a class, and getting the class's selection is probably pointless. The other problem is that even if this were an instance, you would be binding to the selection at the time of the call, which is almost certainly not what you want. You want to track the current selection as it changes.
So what you want is probably something like the following:
[myViewController bind:#"value" toObject:myArrayController withKeyPath:#"selection.isLocked" options:nil];
i have in my project a mainpage interited from uiviewcontroller. and any subpage is inherited from a subviewcontroller, that is an inherited uiviewcontroller, just with some overwritten behaviours and some new functions.
problem in that case is, that the class-model generated by xcode does not display that one inheritation between uiviewcontroller and subviewcontroller. how can i bring xcode to make this arrow there ?
The class-model does not affect anything with your code. As long as your class is said to inherit from UIViewController SubViewController : UIViewController then you are fine. Depending on how many classes you are modeling at once you may have hundreds of lines very close together and you may not be able to see a specific arrow unless you drag your SubViewController way away from everything else. try selecting just that class and see if you get the arrow then. Even if you don't see the arrow it does not mean you have a problem, if you want to be sure that UIViewController is the superclass of SubViewController then just add this chunk of code to your SubViewController class:
+(void)initialize {
NSLog(#"My class is: %#, my superclass is: %#.", [self class], [self superclass]);
}
when i publicate one funktion in the SubViewController, the graphic is correct, even if this is programmaticaly nonsens.