Why doesn't this array need [NSArray array]? - objective-c

This is a little part of the code:
int main (int argc, const char * argv[]) {
#autoreleasepool {
NSProcessInfo *proc = [NSProcessInfo processInfo];
NSArray *myArray = [proc arguments];
...
Why isn't it written like NSArray *myArray = [NSArray arrayWithArray: [proc arguments]];? Also, with ARC does that mean arrays don't need their init methods?

Because [proc arguments]; already returns an NSArray *. Writing NSArray *myArray = [NSArray arrayWithArray: [proc arguments]]; is just redundant.

Related

Objective-C method_exchangeImplementations result is not as expected

I'm learning Objective-C runtime, and try to use method_exchangeImplementations to exchange addObject: method and removeObject: method of NSMutableArray.
My code like this:
int main(int argc, const char * argv[]) {
#autoreleasepool {
Method removeMethod = class_getInstanceMethod(NSMutableArray.class, #selector(removeObject:));
Method addMethod = class_getInstanceMethod(NSMutableArray.class, #selector(addObject:));
method_exchangeImplementations(addMethod, removeMethod);
NSMutableArray *array = [[NSMutableArray alloc] init];
NSObject *obj = [[NSObject alloc] init];
[array removeObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 1, actual print 1
[array addObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 0, actual print 2
}
return 0;
}
I expect exchange add/remove function, but seems like only removeObject: has been exchange to addObject: , addObject: still is addObject to array, now I have two addObject method of NSMutableArray
I'm not sure the reason. I try to exchange other method like uppercaseString/lowercaseString of NSString, that work correct.
OK, I solved problem. Thanks #Willeke for the tip.
The real class of my array is not NSMutableArray, so use NSMutableArray.class in class_getInstanceMethod can't get correct method. Use [array class] is the answer.
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSMutableArray *array = [[NSMutableArray alloc] init];
Method removeMethod = class_getInstanceMethod([array class], #selector(removeObject:));
Method addMethod = class_getInstanceMethod([array class], #selector(addObject:));
method_exchangeImplementations(addMethod, removeMethod);
NSObject *obj = [[NSObject alloc] init];
[array removeObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 1, actual print 1
[array addObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 0, actual print 0
}
return 0;
}

why is this not printing out a grocery list? NSMuteableArray For fast loop enumeration

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSMutableArray *groceries;
NSString *a = (#"loaf of bread");
NSString *b = (#"stick of butter");
NSString *c = (#"big ass cookie");
[groceries addObject:a];
[groceries addObject:b];
[groceries addObject:c];
for (NSString *d in groceries){
NSLog(#"%#", d);
}
}
return 0;
}
Why is this not working? What is wrong? Thanks.
I cannot seem to figure it out at this moment, the for loop defiantly seems to be the hangup.
While you didn't initialize NSMutableArray, it's is nil. Adding object to non-initialized mutable array always give nil.
Firstly you need to initialize groceries:
NSMutableArray *groceries = [NSMutableArray new];
or more liked by me way:
NSMutableArray *groceries = #[].mutableCopy;
In your case, for example, you can declare so:
NSMutableArray *groceries = #[#"loaf of bread", #"stick of butter", #"big ass cookie"].mutableCopy;

NSArray sort arrays

There are several NSArray objects in a NSArray.
Example code is like this
NSArray *a1 = #[#3, #3, #2];
NSArray *a2 = #[#2, #4, #5];
NSArray *a3 = #[#2, #5, #1];
NSArray *array = #[a1, a2, a3];
How do I sort a1, a2 and a3 in numerical/alphabetical/logical order?
Assuming that each array contains only instances of NSNumber this should work:
NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(NSArray *array1, NSArray *array2) {
NSString *str1 = [array1 componentsJoinedByString:#"|"];
NSString *str2 = [array2 componentsJoinedByString:#"|"];
return [str1 compare:str2];
}];
I doubt it'll be particularly efficient with larger data sets though.

what is the use of stringsByAppendingPaths

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSArray *array = [[NSArray alloc] initWithObjects:#"/tmp/1.txt" ,#"/tmp/2.txt", nil];
NSLog(#"%#", array);
NSString *result = [[NSString alloc] init];
NSArray *array2 = [[NSArray alloc]initWithArray:[result stringsByAppendingPaths:array]];
NSLog(#"%#", array2);
}
return 0;
}
The argument we provide to stringsByAppendingPaths: is an array and so is the return type. So what is the use of this NSString method?
Well, you're appending empty string (result), so it doesn't make much sense. But if your receiver contains say /tmp and the array contains 1.txt and 2.txt, getting the array /tmp/1.txt and /tmp/2.txt makes sense.

Arrays of NSObjects in Objective-C

I've created an object, and now I'm trying to create an array full of these objects. I've tried a few different things with no success.
How can I do this?
You can do it one of two ways, with NSArray or NSMutableArray.
id obj1, obj2, obj3;
// This creates a static array
NSArray *array = [NSArray arrayWithObjects: obj1, obj2, obj3, nil];
// This creates a dynamic array
NSMutableArray *mutarray = [NSMutableArray array];
[mutarray addObject:obj1];
[mutarray addObject:obj2];
[mutarray addObject:obj3];
NSMutableArray * arrayOfFoos = [NSMutableArray array];
for (int i = 0; i < 100; ++i) {
Foo * f = [[Foo alloc] init];
[arrayOfFoos addObject:f];
[f release];
}
You can use an NSArray, take a look at Apple's documentation.
If you wanna add them incrementally consider using a mutable collection like an NSMutableArray (here in the doc)