The Objective-C doesn’t provide any keyword for making a class abstract.
However, there are a few abtract classes.
What I know are :
- NSObject
- NSProxy
- NSPreferencePane
- NSView
What else can you think of?
The Objective-C doesn’t provide any keyword for making a class abstract.
However, there are a few abtract classes.
What I know are :
What else can you think of?
Have you ever tried finding the lock icon you can see on Energy Savor system preference on your Mac?
I tried using it for my program, but I couldn’t find it. The reason I want to use it is to enforce root/admin privilege for changing some preference. So, it is quite suitable to use that icon.
I found out that how it can be used in the SFAuthorizationView class reference.

It is very interesting. Is there any other view class which draws an image for itself?
On a Macintosh, there are many ways to communicate among different processes.
When you want to use the collections of the Cocoa for storing non-object types, NSValue and NSNumber are very useful. NSNumber is a child class of the NSValue, and therefore the NSValue has more flexibility.
Let’s take look at the description on what the NSValue can do :
An NSValue object is a simple container for a single C or Objective-C data item. It can hold any of the scalar types such as int, float, and char, as well as pointers, structures, and object ids. The purpose of this class is to allow items of such data types to be added to collection objects such as instances of NSArray or NSSet, which require their elements to be objects. NSValue objects are always immutable.
So, the following code is possible.
// assume ImaginaryNumber defined:
typedef struct {
float real;
float imaginary;
} ImaginaryNumber;
ImaginaryNumber miNumber;
miNumber.real = 1.1;
miNumber.imaginary = 1.41;
NSValue *miValue = [NSValue value: &miNumber
withObjCType:@encode(ImaginaryNumber)]; // encode using the type name
ImaginaryNumber miNumber2;
[miValue getValue:&miNumber2];
Impressive, isn’t it?
However, Apple’s document has a one strange line of explanation which is somewhat ambiguous.
Note that the type you specify must be of constant length. You cannot store C strings, variable-length arrays and structures, and other data types of indeterminate length in an NSValue—you should use NSString or NSData objects for these types. You can store a pointer to variable-length item in an NSValue object.
What does that mean? What if your data is not variable length? Will it be stored correctly?
typedef struct {
int dataSize;
char *data;
int year;
} myStructType1;
When the data points to a character array, will it be encoded correctly?
This is easy to answer. It is variable length. So, the content the data points to is not encoded.
Only the address is encoded. So, if you write a publisher thread which encodes the type and releases allocated memory space for the data, and a consumer thread which decode it to retrieve original data, the decoded myStructType1 instance only contains the address for the data, not the content. So, don’t expect it would store the data. For the purpose, use NSData or NSArchiver.
How about this example?
typedef struct {
int age;
int month;
int day;
} innerType;
typedef struct {
int dataSize;
innerType *innerData;
} myStructType2;
Well.. the innerType is sort of non-variable-length type. So, will it be encoded correctly?
No. Apple’s document is not clear on this. It also encode the address not the content.
So, in this case, you also need to use the NSData.
So, try using the NSValue to convert struct without any member which is a pointer to some other structure.
Then how the NSValue stores? It is kind of shallow copy. Please read this.
Here the address of myCString is passed (&myCString), so the address of the first character of the string is stored in theValue. Note that the NSValue object doesn’t copy the contents of the string, but the pointer itself. If you create an NSValue object with an allocated data item, don’t deallocate its memory while the NSValue object exists.
Today, I posted a long question to the cocoa mailing list of the Apple Computer. At that time, I was thinking about 3 different things at the same time, so my question was not quite correct.
By the way, one guy there told me about an environmental variable which helps memory debugging.
For more, please read Memory Usage Performance Guidelines: Enabling the Malloc Debugging Features
This is very important issue in memory management in Cocoa. About 10 years ago, I didn’t worry about this issue much, because at that time things were clear and API were not that complicated. However, it is not true any more. Due to performance issues, copying memory is avoided if possible, and in that case shallow copy is prefered. ( Nowadays, even weak reference or strong reference should be considered also. )
Collections in Cocoa are usually shallow-copy-based, if a programmers want it in the other way. Apple prepares deep copy option for those users.
Then, how about NSValue and NSNumber? Recently I started using these two classes heavily. They are used to make opaque types like int, float, or other C structures work with the Cocoa collections. Any objects based on NSObject can be put into collections. However the primitive types can’t be. So, they should be wrapped in NSValue and NSNumber. How to do so is shown below.
typedef struct complexTypeConveyer
{
int dataSize;
int year;
int tag;
} complexTypeConveyer;
// Move to the conveyer
complexTypeConveyer *theConveyer = (complexTypeConveyer *)malloc(sizeof(complexTypeConveyer));;
theConveyer->dataSize = dataSet.dataSize;
theConveyer->year = dataSet.year;
theConveyer->tag = dataSet.tag;
NSValue *aValue = [NSValue valueWithBytes:theConveyer objCType:@encode(complexTypeConveyer)];
The [NSValue valueWithBytes: objCType:] is a kind of a convenience method. You don’t need to wrap each data member of a given data structure.
I will post a separate article on this, because it has some issues with pointers pointing to other structures.
Then, how will the data be kept? It is self-contained, or in other words, the data, theConveyer holds, are deep-copied shallow-copied. But Apple’s document doesn’t clearly mention it. So, test it for yourself and check if things work as you want.
The Objective-C 2.0 introduced a garbage collector. It is nice and very simple to use.
However, I still prefer old style, release, retain, copy model. The reason is simple. You can control when to retain and release object. By doing so, you can manage memory more well. I don’t think old style is difficult to understand.
However, when you are involved in a group project in which a few programmers join, you don’t know how others write memory related codes. In such a case, garbage collection can be better.
Anyway, when making threads, you are supposed to make a dedicated memory pool for yourself. In the end of such thread function, you should issue :
[pool release];
However, it can raises BAD_ACCESS_EXE exception. Why? It is because certain objects are released to much. Especially when you deal with collections, this can happen, because Apple’s explanation when objects are retained, just referenced, or copied is not clear sometimes.
How to figure out which causes the exception and where it happens?
There are good documentation on the issue.
Although I use Korean everyday, I didn’t have enough chance to figure out how the Unicode is actually designed.
The Mac OS X supports the Unicode, and when they say “Unicode”, it usually means the UTF-16, which is a 2 byte version of the Unicode.
One day I noticed a strange symptom. An NSString made with “자연” looked different from the same one in an FCP project file.
I wonder why and asked to the Apple’s Cocoa mailing list.
I got an answer from Ken Thomas and he suggested to check Unicode normalization.
Here is the link :
Unicode Standard Annex #15
Unicode Normalization Forms
There are 4 different way of representing Unicode.
Form D means Canonical “D”ecomposition, while Form C means Canonical “C”omposition.
The K in KD and KC mean “Compatibility”.
The link above explains what they are very well using pictures. So, take a look at it.
Now, you will be able to understand what -precomposed.. and -decomposed.. mean in the NSString documentation for these methods.
There are two additional issues I would like to mention.
First, we know that the Mac OS X uses Unicode natively. However which Unicode representation does it use?
- (const char*)fileSystemRepresentation of the NSString and - (const char*)fileSystemRepresentationWithPath:(NSString *)path returns the file name in Unicode in a way the MacOS X uses.
It is said to be mostly decomposed version. So, when you try opening a file by choosing one using NSOpenPanel, it would contain the string in decomposed way.
Second… then how we compare two Unicode strings? I guess we should take care of the two cases. But, the NSString is smart enought to handle them for us.
The compare: methods of the NSString can accept whatever forms and it can compare a composed version with a decomposed version. If the twos are actually for the same characters or words, it returns NSOrderedSame, which means that they are the same.
Impressive, isn’t it?
I added han9kin’s blog to the link list on the side.
I got to know han9kin at http://www.osxdev.org. He wrote a Korean input method with the Carbon TSM and is now implementing another one with IMKit for the Leopard, Hanulim, which means big consonance. The Han, 韓, has meant “big”, “great”. Korean people is 韓民族, while pure Chinese is 漢. Same pronounciation in Korean, but different meaning. Han9kin can be understood as Han 9k in.
You can check the Hanulim project at http://code.google.com/p/hanulim/
9 sounds like Goo. By adding K, it becomes Gook. in is pronounced as “in”. In is 人. The Republic of Korea’s official name in Korean is 大韓民國, or 韓國 in short, and it is the pronouciation of Han9k.
So, he made his nick name on the Internet very wisely and smart.
han9kin means a Korean, i.e a Korean people.
By the way, 韓 is originally same to 桓. Currently students from element school to high school are tought that Korea’s first country is Go-Cho-Sun, meaning Old Chosun, but it is twisted history by Japanese during the japanese reign. Before that there were, 桓國 and 伸市. It is almost 15,000 years ago, but more archaeological evidence are being found and archaeologists say that Korea’s history can be much longer.
The setSize of NSImage behaves differently on the Leopard and the Tiger.
According to the NSImage class reference for the Leopard, it says :
“Changing the size of an NSImage after it has been used effectively resizes the image.”
It behaves as such on the Leopard, but not on the Tiger.
On the Tiger, the setSize doesn’t resize an image.
Take a look at the source code below.
NSImage *anImage; NSSize imageSize; NSString *imagePath; imagePath = [[NSBundle mainBulde] pathForImageResource:@"myLogo.eps"]; anImage = [[NSImage alloc] initWithContentsOfFile:imagePath]; imageSize = [anImage size]; imageSize.width *= 0.3; imageSize.height *= 0.3; [anImage setScaleWhenResized:YES]; // For the Tiger [anImage setSize:imageSize];
The eps format is a postscript format with which a scaling can be used.
The Leopard version of the setSize method of the NSImage automatically scales and draws the image as such.
However, on the Tiger the setScaleWhenResized with YES as its parameter should be explicitly called.
Documentation for the Tiger explains this much better.
For other approaches, Sci-Fi Hi-Fi hosted a good article.
Recent Comments